BZOJ4552

来源:互联网 发布:欧洲十国游 知乎 编辑:程序博客网 时间:2024/06/15 01:13

O(nlogn),可分裂合并的线段树

嗨呀,写死我了

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<set>#define Sum(a) ((a)?(a)->sum:0)using namespace std;struct tree{    tree* l,* r;    int sum;    tree(){l=r=0;sum=0;}    void update(){        sum=Sum(l)+Sum(r);    }}; struct data{    int l,r,type;    tree* ptr;    data(int l,int r,int type,tree*ptr):        l(l),r(r),type(type),ptr(ptr){}    int operator<(const data& d)const{        return r<d.r;    }};typedef set<data>::iterator sit;tree* merge(tree*& a,tree* b,int l,int r){//  printf("[%d,%d]",a,b);    if(!a)return b;    if(!b)return a;    if(l==r){        a->sum+=b->sum;        return a;    }    int mid=l+r>>1;    a->l=merge(a->l,b->l,l,mid);    a->r=merge(a->r,b->r,mid+1,r);    a->update();    return a;}tree* split(tree*& a,int l,int r,int k){         if(!k||!a)return 0;//  printf(" S{%d,%d,%d}",a,l,r);    if(l==r){        tree* ret=new tree;        ret->sum=a->sum;        a=0;        return ret;    }    tree* ret=new tree;    int mid=l+r>>1;    if(Sum(a->l)<k){        tree* f=split(a->r,mid+1,r,k-Sum(a->l));        ret->r=f,ret->l=a->l,a->l=0;//      printf("[%d,%d,%d]",a->l,f,k);        ret->update();        a->update();    } else {        tree* f=split(a->l,l,mid,k);        ret->l=f,ret->r=0;        ret->update();        a->update();    }//  printf("{%d}\n",k);    return ret;}void insert(tree*& a,int l,int r,int k){    if(!a)a=new tree;    a->sum++;    if(l==r)return ;    int mid=l+r>>1;    if(k<=mid)insert(a->l,l,mid,k);    else insert(a->r,mid+1,r,k);}int ask(tree* a,int l,int r,int k){//  printf("[%d,%d]",a->sum,k);    if(l==r)return l;    int mid=l+r>>1;    if(Sum(a->l)<k)return ask(a->r,mid+1,r,k-Sum(a->l));    else return ask(a->l,l,mid,k);}tree* newnode(int k,int n){    tree* ret=0;    insert(ret,1,n,k);    return ret;}void print(tree* a,int l,int r,bool type){    if(!a)return ;    if(l==r){        printf("%d ",l);        return ;    }    int mid=l+r>>1;    if(type){        print(a->r,mid+1,r,type);        print(a->l,l,mid,type);    } else {        print(a->l,l,mid,type);        print(a->r,mid+1,r,type);        }}int n,m;set<data>st;int main(){//  freopen("in.txt","r",stdin);    scanf("%d%d",&n,&m);    for(int i=1,a;i<=n;++i)        scanf("%d",&a),st.insert(data(i,i,0,newnode(a,n)));    for(int i=1,k,op,l,r;i<=m;++i){        scanf("%d%d%d",&op,&l,&r);        tree* res=0;        sit it=st.lower_bound(data(0,l,0,0));        while(it!=st.end()&&it->l<=r){            data d=*it;            sit xt=it;xt++;            st.erase(it);it=xt;            tree* g=d.ptr;            if(d.l<=l&&r<=d.r){                                 if(op==d.type){                    st.insert(data(d.l,d.r,d.type,g));                    goto end;                } else if(d.type){                    tree* ptr=split(g,1,n,d.r-r);                    res=split(g,1,n,r-l+1);                    if(Sum(g)!=0)st.insert(data(d.l,l-1,d.type,g));                    if(Sum(ptr)!=0)st.insert(data(r+1,d.r,d.type,ptr));                } else {                    tree* ptr=split(g,1,n,l-d.l);                    res=split(g,1,n,r-l+1);                    if(Sum(ptr)!=0)st.insert(data(d.l,l-1,d.type,ptr));                    if(Sum(g)!=0)st.insert(data(r+1,d.r,d.type,g));                 }                st.insert(data(l,r,op,res));                goto end;                             } else if(l<=d.l&&d.r<=r){                res=merge(res,g,1,n);            } else if(d.l<l){                if(d.type){                    k=d.r-l+1;                    tree* ptr=split(g,1,n,k);                    res=merge(res,ptr,1,n);                    if(Sum(g)!=0)st.insert(data(d.l,l-1,d.type,g));                } else {                    k=l-d.l;                    tree* ptr=split(g,1,n,k);                    res=merge(res,g,1,n);                    if(Sum(ptr)!=0)st.insert(data(d.l,l-1,d.type,ptr));                }            } else if(d.r>r){                if(d.type){                    k=d.r-r;                    tree* ptr=split(g,1,n,k);                    res=merge(res,g,1,n);                    if(Sum(ptr)!=0)st.insert(data(r+1,d.r,d.type,ptr));                } else {                    k=r-d.l+1;                    tree* ptr=split(g,1,n,k);                    res=merge(res,ptr,1,n);                    if(Sum(g)!=0)st.insert(data(r+1,d.r,d.type,g));                }            }        }        st.insert(data(l,r,op,res));        end:;             }    int q;scanf("%d",&q);    sit it=st.lower_bound(data(q,q,0,0));    if(!it->type)printf("%d",ask(it->ptr,1,n,q-it->l+1));    else printf("%d",ask(it->ptr,1,n,it->r-q+1));}


0 0
原创粉丝点击