bzoj 3196: Tyvj 1730 二逼平衡树

来源:互联网 发布:人工智能电影解析 编辑:程序博客网 时间:2024/05/21 11:36

线段树套平衡树做法;


#include<bits/stdc++.h>#define ls x<<1#define rs x<<1|1using namespace std;const int N=200005;const int M=3000001;const int inf=0x3f3f3f3f;int root[N],sum[M],s[M],ch[M][2],val[M],key[M],n,m,tot=0,a[N];inline void up(int x){s[x]=sum[x]+s[ch[x][0]]+s[ch[x][1]];}int newnode(int x,int v){int t=++tot;ch[t][0]=ch[t][1]=0;val[t]=v;key[t]=rand();sum[t]=s[t]=1;return t;}void rotate(int& x,int d){    int t=ch[x][d^1];ch[x][d^1]=ch[t][d];ch[t][d]=x,up(x),up(t),x=t;}void insert(int &x,int v){    if(!x){x=newnode(x,v);return;}    if(val[x]==v){sum[x]++;up(x);return;}    int d=(val[x]<v);    insert(ch[x][d],v);    if(key[ch[x][d]]<key[x])rotate(x,d^1);    up(x);}void del(int &x,int v){if(!x)return;    if(val[x]==v){        if(sum[x]>1){sum[x]--;up(x);return;}        else{            if(ch[x][0]*ch[x][1]==0){int k=ch[x][1]+ch[x][0];x=k;return;}            int d=(key[ch[x][0]]<key[ch[x][1]]);            rotate(x,d);del(ch[x][d],v);        }    }    del(ch[x][val[x]<v],v);    up(x);}int getrank(int x,int v){if(!x)return 0;    if(val[x]==v)return s[ch[x][0]];    if(val[x]<v)return s[ch[x][0]]+sum[x]+getrank(ch[x][1],v);    else return getrank(ch[x][0],v);}int getpro(int x,int v){if(!x)return -inf;    if(val[x]<v)return max(val[x],getpro(ch[x][1],v));    else return getpro(ch[x][0],v);}int getaft(int x,int v){if(!x)return inf;    if(val[x]>v)return min(val[x],getaft(ch[x][0],v));    else return getaft(ch[x][1],v);}void build(int x,int l,int r,int pos,int v){    insert(root[x],v);    if(l==r)return;    int mid=(l+r)>>1;    if(pos<=mid)build(ls,l,mid,pos,v);    else build(rs,mid+1,r,pos,v);}int rank(int x,int l,int r,int ql,int qr,int v){int ans=0;    if(l>=ql && r<=qr){return getrank(root[x],v);}    int mid=(l+r)>>1;    if(ql<=mid)ans+=rank(ls,l,mid,ql,qr,v);    if(qr>mid)ans+=rank(rs,mid+1,r,ql,qr,v);    return ans;}int kth(int ql,int qr,int k){    int l=0,r=inf,ans;    while(l<=r){int mid=(l+r)>>1;        if(rank(1,1,n,ql,qr,mid)<=k-1){l=mid+1;ans=mid;}   ///        else r=mid-1;    }    return ans;}void change(int x,int l,int r,int pos,int v){    del(root[x],a[pos]);insert(root[x],v);    if(l==r)return;    int mid=(l+r)>>1;    if(pos<=mid)change(ls,l,mid,pos,v);    else change(rs,mid+1,r,pos,v);}int pro(int x,int l,int r,int ql,int qr,int v){int ans=-inf;    if(l>=ql && r<=qr){return getpro(root[x],v);}    int mid=(l+r)>>1;    if(ql<=mid)ans=max(ans,pro(ls,l,mid,ql,qr,v));    if(qr>mid)ans=max(ans,pro(rs,mid+1,r,ql,qr,v));    return ans;}int aft(int x,int l,int r,int ql,int qr,int v){int ans=inf;    if(l>=ql && r<=qr){return getaft(root[x],v);}    int mid=(l+r)>>1;    if(ql<=mid)ans=min(ans,aft(ls,l,mid,ql,qr,v));    if(qr>mid)ans=min(ans,aft(rs,mid+1,r,ql,qr,v));    return ans;}void debug(int x) {        if(!x)return;        debug(ch[x][0]);        printf("%d :( val: %d sum: %d size: %d ls:%d rs: %d)\n",x,val[x], sum[x],s[x], ch[x][0], ch[x][1]);        debug(ch[x][1]);    }void bug(int x,int l,int r){    printf("root[%d] %d %d \n",x,l,r);debug(root[x]);    if(l==r)return;    int mid=(l+r)>>1;    bug(ls,l,mid);bug(rs,mid+1,r);}int main(){//freopen("in.in","r",stdin);//freopen("out.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)scanf("%d",&a[i]);    for(int i=1;i<=n;i++)build(1,1,n,i,a[i]);    for(int i=1;i<=m;i++)    {        int f;scanf("%d",&f);        int x,y,k;        switch(f)        {            case 1:scanf("%d%d%d",&x,&y,&k);printf("%d\n",rank(1,1,n,x,y,k)+1);break;            case 2:scanf("%d%d%d",&x,&y,&k);printf("%d\n",kth(x,y,k));break;            case 3:scanf("%d%d",&x,&y);change(1,1,n,x,y);a[x]=y;break;            case 4:scanf("%d%d%d",&x,&y,&k);printf("%d\n",pro(1,1,n,x,y,k));break;            case 5:scanf("%d%d%d",&x,&y,&k);printf("%d\n",aft(1,1,n,x,y,k));break;        }     }//    printf("\n\n");bug(1,1,n);    return 0;}

好慢…难道说这题的意思是用平衡树的都是…….

0 0