AC日记——NOI2016区间 bzoj 4653

4653

思路:

  线段树,指针滑动;

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define maxm 200005
#define maxn_ maxn<<2
#define INF 0x7fffffff
struct TreeNodeType {
    int l,r,dis,mid,flag;
};
struct TreeNodeType tree[maxn_];
struct QueryType {
    int l,r,len;
    bool operator <(const QueryType pos)const
    {
        return pos.len>len;
    }
};
struct QueryType qu[maxn];
int n,m,bi[maxn_],cnt,size,ans=INF;
inline void in(int &now)
{
    char Cget=getchar();now=0;
    while(Cget>‘9‘||Cget<‘0‘)Cget=getchar();
    while(Cget>=‘0‘&&Cget<=‘9‘)
    {
        now=now*10+Cget-‘0‘;
        Cget=getchar();
    }
}
void build(int now,int l,int r)
{
    tree[now].l=l,tree[now].r=r;
    if(l==r) return;tree[now].mid=l+r>>1;
    build(now<<1,l,tree[now].mid);
    build(now<<1|1,tree[now].mid+1,r);
}
inline void pushdata(int now)
{
    tree[now<<1].dis+=tree[now].flag;
    tree[now<<1].flag+=tree[now].flag;
    tree[now<<1|1].dis+=tree[now].flag;
    tree[now<<1|1].flag+=tree[now].flag;
    tree[now].flag=0;
}
void updata(int now,int l,int r,int x)
{
    if(tree[now].l>=l&&tree[now].r<=r)
    {
        tree[now].dis+=x,tree[now].flag+=x;
        return;
    }
    if(tree[now].flag!=0) pushdata(now);
    if(l<=tree[now].mid) updata(now<<1,l,r,x);
    if(r>tree[now].mid) updata(now<<1|1,l,r,x);
    tree[now].dis=max(tree[now<<1].dis,tree[now<<1|1].dis);
}
int query(int now,int l,int r)
{
    if(tree[now].l>=l&&tree[now].r<=r) return tree[now].dis;
    if(tree[now].flag!=0) pushdata(now);
    int res=0;
    if(l<=tree[now].mid) res=max(res,query(now<<1,l,r));
    if(r>tree[now].mid) res=max(res,query(now<<1|1,l,r));
    return res;
}
int main()
{
    in(n),in(m);
    for(int i=1;i<=n;i++)
    {
        in(qu[i].l),in(qu[i].r);
        qu[i].len=qu[i].r-qu[i].l+1;
        bi[++cnt]=qu[i].l,bi[++cnt]=qu[i].r;
    }
    sort(qu+1,qu+n+1);
    sort(bi+1,bi+cnt+1);
    size=unique(bi+1,bi+cnt+1)-bi-1;
    int now=0,pos;build(1,1,size);
    for(int i=1;i<=n;i++)
    {
        qu[i].l=lower_bound(bi+1,bi+size+1,qu[i].l)-bi;
        qu[i].r=lower_bound(bi+1,bi+size+1,qu[i].r)-bi;
        updata(1,qu[i].l,qu[i].r,1);
        while(tree[1].dis>=m)
        {
            now++,pos=query(1,qu[now].l,qu[now].r);
            if(pos>=m) ans=min(qu[i].len-qu[now].len,ans);
            updata(1,qu[now].l,qu[now].r,-1);
        }
    }
    printf("%d\n",ans==INF?-1:ans);
    return 0;
}
时间: 2025-01-12 14:14:25

AC日记——NOI2016区间 bzoj 4653的相关文章

AC日记——[ZJOI2012]网络 bzoj 2816

2816 思路: 多个LCT: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 10005 #define ll long long int val[maxn]; struct LinkCutTreeType { int f[maxn],Max[maxn],ch[maxn][2],rev[maxn],sta[maxn],top,cnt[maxn]; void updata(int now) { Max[now]=va

AC日记——[Hnoi2017]影魔 bzoj 4826

4826 思路: 主席树矩阵加减+单调栈预处理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define ll long long #define maxtree maxn*30 class PTreeType { private: int ch[maxtree][2],root[maxn],tot,head[maxn],li[maxn<<1],ri[maxn<<1],E

AC日记——[SCOI2007]蜥蜴 bzoj 1066

1066 思路: 网络流最大流: 拆点,每个点拆成两个,流量为这个点的高度: 注意,文中说的距离是曼哈顿距离(劳资以为开根号wa了不知道多少次): 每两个距离不大于d的点连边,流量inf: 如果距离能够延伸到边界外,就将这个点连向t: 最后输出,蜥蜴个数减去最大流: 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <alg

AC日记——Rmq Problem bzoj 3339

3339 思路: 恶心: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 200005 struct TreeNodeType { int l,r,dis,mid,flag; bool if_; }; struct TreeNodeType tree[maxn<<2

AC日记——[Ahoi2013]作业 bzoj 3236

3236 思路: 莫队+树状数组维护: 代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005 struct QueryType { int l,r,a,b,id; }; struct QueryType qu[maxn*10

AC日记——[HNOI2008]越狱 bzoj 1008

1008 思路: 越狱情况=总情况-不越狱情况: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define ll long long ll poww(ll x,ll e,ll k) { ll res=1,pos=x;pos%=k; while(e) { if(e&1) res=(res*p

[Noi2016]区间[离散化+线段树维护+决策单调性]

4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 621  Solved: 329[Submit][Status][Discuss] Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri. 对于一个合法的

AC日记——Aragorn&#39;s Story HDU 3966

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10510    Accepted Submission(s): 2766 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lor

【BZOJ4653】[Noi2016]区间 双指针法+线段树

[BZOJ4653][Noi2016]区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri. 对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度.区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值. 求所有合法方案中最小