【bzoj 3110】K大数查询(整体二分)

来源:互联网 发布:JAVA中 异常类型 编辑:程序博客网 时间:2024/04/30 06:39

传送门biu~
整体二分。我选择把数据用树状数组维护,树状数组可以支持区间修改区间查询。
你们可能永远不会知道一道题没开long long要调多久QAQ

#include<bits/stdc++.h>#define lowbit(x) (x&(-x))using namespace std;#define int long longstruct data{    int opt,x,y,c;}a[50005];int n,m,tim;int ans[50005];int p[50005],tmp[2][50005];int tree[2][50005],t[2][50005];inline void add(int opt,int x,int num){    while(x<=n){        if(t[opt][x]!=tim)  tree[opt][x]=0;        t[opt][x]=tim;        tree[opt][x]+=num;        x+=lowbit(x);    }}inline void add(int l,int r){    add(0,l,1);add(0,r+1,-1);    add(1,l,l);add(1,r+1,-(r+1));}inline int search(int opt,int x){    int re=0;    while(x){        if(t[opt][x]!=tim)  tree[opt][x]=0;        t[opt][x]=tim;        re+=tree[opt][x];        x-=lowbit(x);    }    return re;}inline int search(int x){    return (x+1)*search(0,x)-search(1,x);}void binary_search(int L,int R,int l,int r){    if(L>R || l>r)  return;    ++tim;    int mid=l+r>>1;    if(l==r){        for(int i=L;i<=R;++i){            if(a[p[i]].opt==2)  ans[p[i]]=mid;        }        return;    }    tmp[0][0]=tmp[1][0]=0;    for(int i=L;i<=R;++i){        int x=p[i];        if(a[x].opt==1){            if(a[x].c<=mid)     tmp[0][++tmp[0][0]]=x;            else{                tmp[1][++tmp[1][0]]=x;                add(a[x].x,a[x].y);            }        }        else{            int tot=search(a[x].y)-search(a[x].x-1);            if(tot<a[x].c){                a[x].c-=tot;                tmp[0][++tmp[0][0]]=x;            }            else tmp[1][++tmp[1][0]]=x;        }    }    int rL=L+tmp[0][0];    memcpy(p+L,tmp[0]+1,sizeof(p[0])*tmp[0][0]);    memcpy(p+rL,tmp[1]+1,sizeof(p[0])*tmp[1][0]);    binary_search(L,rL-1,l,mid);    binary_search(rL,R,mid+1,r);}#undef intint main(){#define int long long    scanf("%lld%lld",&n,&m);    for(int i=1;i<=m;++i)   scanf("%lld%lld%lld%lld",&a[i].opt,&a[i].x,&a[i].y,&a[i].c),p[i]=i;    binary_search(1,m,1,n);    for(int i=1;i<=m;++i){        if(a[i].opt==2) printf("%lld\n",ans[i]);    }    return 0;}