zoj 2112 Dynamic Rankings

区间第k大问题,因为这个是动态的,有修改,所以划分树是搞不定的。

第一次写树套树,也就是线段树套平衡树,线段树的每个节点是一个平衡树。

查询的时候二分枚举答案,然后判断当前枚举的数是不是第k大的。

这里我的平衡树选择的是treap,但是释放空间那儿写的好丑。。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int inf=~0u>>1;
  6 const int N=(int)1e5+10;
  7 const int maxn=(int)1e9+1;
  8 #define lson l,m,n<<1
  9 #define rson m+1,r,n<<1|1
 10 int x[N];
 11 struct Treap{
 12     struct node{
 13         node *ch[2];
 14         int v,p,sz;
 15         node(int _v,node *n):
 16             v(_v){ch[0]=ch[1]=n;p=rand();sz=1;}
 17         void update(){sz=ch[0]->sz+ch[1]->sz+1;}
 18     };
 19     node *root,*null;
 20     Treap(){
 21     }
 22     void init(){
 23         null=new node(0,0);null->sz=0;null->p=inf;
 24         null->ch[0]=null->ch[1]=null;
 25         root=null;
 26     }
 27     void rotate(node *&t,bool d){
 28         node *_t=t->ch[d];
 29         t->ch[d]=_t->ch[!d];
 30         _t->ch[!d]=t;
 31         _t->update();
 32         t->update();
 33         t=_t;
 34     }
 35     void __insert(node *&t,int val){
 36         if(t==null){
 37             t=new node(val,null);
 38             return;
 39         }
 40         bool d=val > t->v;
 41         __insert(t->ch[d],val);
 42         if(t->ch[d]->p < t->p)rotate(t,d);
 43         t->update();
 44     }
 45     void __del(node *&t,int val){
 46         if(t==null)return;
 47         if(val == t->v){
 48             bool d = t->ch[1]->p < t->ch[0]->p;
 49             if(t->ch[d]==null){
 50                 delete t;
 51                 t=null;
 52                 return;
 53             }
 54             rotate(t,d);
 55             __del(t->ch[!d],val);
 56         }else{
 57             bool d=val > t->v;
 58             __del(t->ch[d],val);
 59         }
 60         t->update();
 61     }
 62     int __rank(node *t,int val){
 63         if(t==null)return 0;
 64         int num=t->ch[0]->sz;
 65         if(val< t->v)return __rank(t->ch[0],val);
 66         return num+1+__rank(t->ch[1],val);
 67     }
 68     void __show(node *x){
 69         if(x==null)return;
 70         __show(x->ch[0]);
 71         printf("%d ",x->v);
 72         __show(x->ch[1]);
 73     }
 74     void insert(int val){
 75         __insert(root,val);
 76     }
 77     void del(int val){
 78         __del(root,val);
 79     }
 80     int rank(int val){
 81         return __rank(root,val);
 82     }
 83     void show(){
 84         __show(root);
 85         puts("");
 86     }
 87     void __fre(node *t){
 88         if(t==null)return;
 89         __fre(t->ch[0]);
 90         __fre(t->ch[1]);
 91         delete t;
 92     }
 93     void fre(){
 94         __fre(root);
 95     }
 96 };
 97 struct segtree{
 98     Treap s[N<<2];
 99     void build(int l,int r,int n){
100         s[n].init();
101         for(int i=l;i<=r;i++)
102             s[n].insert(x[i]);
103         if(l==r)return;
104         int m=(l+r)>>1;
105         build(lson);
106         build(rson);
107     }
108     void del(int l,int r,int n){
109         s[n].fre();
110         if(l==r)return;
111         int m=(l+r)>>1;
112         del(lson);
113         del(rson);
114     }
115     void update(int nn,int a,int l,int r,int n){
116         s[n].del(x[nn]);
117         s[n].insert(a);
118         if(l==r)return;
119         int m=(l+r)>>1;
120         if(nn<=m)update(nn,a,lson);
121         else update(nn,a,rson);
122     }
123     int query(int ll,int rr,int val,int l,int r,int n){
124         if(ll==l&&rr==r){
125             return s[n].rank(val);
126         }
127         int m=(l+r)>>1;
128         if(rr<=m)return query(ll,rr,val,lson);
129         else if(ll>m)return query(ll,rr,val,rson);
130         else return query(ll,m,val,lson)+query(m+1,rr,val,rson);
131     }
132 };
133 segtree T;
134 int n;
135 int check(int L,int R,int val,int k){
136     int a=T.query(L,R,val-1,1,n,1);
137     int b=T.query(L,R,val,1,n,1);
138     if(k>a&&k<=b)return 1;
139     if(k<=a)return 0;
140     if(k>b)return -1;
141 }
142 int bs(int l,int r,int L,int R,int k){
143     while(l<=r){
144         int m=(l+r)>>1;
145         int res=check(L,R,m,k);
146         if(res==1)return m;
147         else if(res==-1)l=m+1;
148         else r=m-1;
149     }
150 }
151 int main(){
152     int cas;
153     scanf("%d",&cas);
154     int m;
155     char op[5];
156     int l,r,k;
157     while(cas--){
158         scanf("%d%d",&n,&m);
159         for(int i=1;i<=n;i++)scanf("%d",&x[i]);
160         T.build(1,n,1);
161 
162         while(m--){
163             scanf("%s",op);
164             if(op[0]=='Q'){
165                 scanf("%d%d%d",&l,&r,&k);
166                 int ans=bs(0,maxn,l,r,k);
167                 printf("%d\n",ans);
168             }else{
169                 scanf("%d%d",&l,&r);
170                 T.update(l,r,1,n,1);
171                 x[l]=r;
172             }
173         }
174         T.del(1,n,1);
175     }
176     return 0;
177 }

 

 

posted @ 2013-04-24 20:31  silver__bullet  阅读(224)  评论(0编辑  收藏  举报