首页 > 代码库 > BZOJ 1901 Dynamic Rankings

BZOJ 1901 Dynamic Rankings

题面:

1901: Zju2112 Dynamic Rankings

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 8088  Solved: 3364
[Submit][Status][Discuss]

Description

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1
],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改
变后的a继续回答上面的问题。

Input

第一行一个数字N,代表测试组数
对于每组数据第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
分别表示序列的长度和指令的个数。
第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
接下来的m行描述每条指令
每行的格式是下面两种格式中的一种。 
Q i j k 或者 C i t 
Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t

Output

 对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Sample Input

1
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6

HINT

m,n≤10000。

Source

题意:带修改区间k小值,线段树+splay。

技术分享
  1 #include<stdio.h>
  2 using namespace std;
  3 #define maxn 500001
  4 #define lson id<<1,l,mid
  5 #define rson id<<1|1,mid+1,r
  6 int s[50001];
  7 int n,m;
  8 struct node
  9 {
 10     int w,size,count;
 11     node *fa,*son[2];
 12 }tree[maxn<<2],*stk[maxn<<2];
 13 int top,indx;
 14 class Splay
 15 {
 16     private:
 17         node *newnode(int w,node *f)
 18         {
 19             node *t;
 20             if(top)t=stk[--top];
 21             else t=&tree[indx++];
 22             t->w=w;t->size=t->count=1;
 23             t->fa=f;t->son[0]=t->son[1]=NULL;
 24             return t;
 25         }
 26         inline void freenode(node *t)
 27         {
 28             stk[top++]=t;
 29         }
 30         inline int size(node *t)
 31         {
 32             return t==NULL?0:t->size;
 33         }
 34         inline bool Son(node *f,node *t)
 35         {
 36             return f==NULL?0:f->son[1]==t;
 37         }
 38         inline void update(node *t)
 39         {
 40             if(t==NULL)return ;
 41             t->size=t->count+size(t->son[0])+size(t->son[1]);
 42         }
 43         inline void connect(node *f,node *t,bool flag)
 44         {
 45             if(f==NULL)root=t;
 46             else f->son[flag]=t;
 47             if(t!=NULL)t->fa=f;
 48         }
 49         void rotate(node *t)
 50         {
 51             node *f=t->fa;node *g=f->fa;
 52             bool a=Son(f,t),b=!a;
 53             connect(f,t->son[b],a);
 54             connect(t,f,b);
 55             connect(g,t,Son(g,f));
 56             update(f);update(t);
 57         }
 58         void splay(node *t,node *p)
 59         {
 60             if(t==NULL)return ;
 61             node *f,*g;
 62             while(t->fa!=p)
 63             {
 64                 f=t->fa;g=f->fa;
 65                 if(g==p)rotate(t);
 66                 else
 67                 if(Son(f,t)^Son(g,f))rotate(t),rotate(t);
 68                 else rotate(f),rotate(t);
 69             }
 70         }
 71         node *find(int w)
 72         {
 73             node *t=root;
 74             while(t!=NULL&&t->w!=w)
 75                 t=t->son[w>=t->w];
 76             return splay(t,NULL),t;
 77         }
 78         node *insert(node *t,int w)
 79         {
 80             node *p=t->son[w>=t->w];
 81             if(p==NULL) 
 82                 p=t->son[w>=t->w]=newnode(w,t);
 83             else
 84                 p=insert(p,w);
 85             return update(t),p;
 86         }
 87         void erase(node *t)
 88         {
 89             if(t->son[0]==NULL)
 90             {
 91                 connect(NULL,t->son[1],0);
 92                 update(root);
 93             }
 94             else
 95                 if(t->son[1]==NULL)
 96                 {
 97                     connect(NULL,t->son[0],0);
 98                     update(root);
 99                 }
100                 else   
101                 {
102                     node *p=t->son[0];
103                     while(p->son[1]!=NULL)   
104                         p=p->son[1];
105                     splay(p,t);
106                     connect(NULL,p,0);
107                     connect(p,t->son[1],1);
108                     update(root);
109                 }
110             freenode(t);
111         }
112         void erase(node *t,int k)
113         {
114             t->count-=k;
115             if(t->count<=0)
116                 erase(t);
117             else
118                 update(t);
119         }
120     public:
121         int l,r;
122         node *root;
123         Splay()
124         {
125             root=NULL;
126         }
127         void insert(int w)
128         {
129             if(find(w)!=NULL)
130                 ++root->count,update(root);
131             else
132                 if(root==NULL)  
133                     root=newnode(w,NULL);
134                 else
135                     splay(insert(root,w),NULL);
136         }
137         void erase(int w)
138         {
139             if(find(w)!=NULL)   
140                 erase(root,1);
141         }
142         int RANK(node *t,int w)
143         {
144             if(t==NULL)
145                 return 0;
146             if(t->w==w)
147                 return size(t->son[0]);
148             if(t->w>w)
149                 return RANK(t->son[0],w);
150             return size(t->son[0])+t->count+RANK(t->son[1],w); 
151         }
152         void clear()
153         {
154             root=NULL;
155         }
156 }a[maxn<<2];
157 int cnt,xx;
158 void clear()
159 {
160     for(int i=1;i<=cnt;i++)
161         a[i].clear();
162     cnt=0;
163 }
164 void build(int id,int l,int r)
165 {
166     ++cnt;
167     a[id].l=l;a[id].r=r;
168     for(int i=l;i<=r;i++)    
169         a[id].insert(s[i]);
170     if(l==r)
171         return ;
172     int mid=(l+r)>>1;
173     build(lson);
174     build(rson);
175 }
176 void change(int id,int p,int w)
177 {
178     a[id].erase(s[p]);
179     a[id].insert(w);
180     if(a[id].l==a[id].r)
181         return ;
182     int mid=(a[id].l+a[id].r)>>1;
183     if(p<=mid)   
184         change(id<<1,p,w);
185     else
186         change(id<<1|1,p,w);
187 }
188 int query(int id,int l,int r,int w)
189 {
190     if(l<=a[id].l&&a[id].r<=r)
191         return a[id].RANK(a[id].root,w);
192     int mid=(a[id].l+a[id].r)>>1;
193     if(r<=mid)
194         return query(id<<1,l,r,w);
195     else
196         if(l>mid)
197             return query(id<<1|1,l,r,w);
198         else
199             return query(id<<1,l,mid,w)+query(id<<1|1,mid+1,r,w);
200 }
201 int QUEST(int l,int r,int k)
202 {
203     int L=0,R=1e9,mid,ans,x;
204     while(L<=R)
205     {
206         mid=L+R>>1;
207         x=query(1,l,r,mid);
208         if(x<=k-1)
209             L=mid+1,ans=mid;
210         else
211             R=mid-1;
212     }
213     return ans;
214 }
215 int main()
216 {
217     char ss[11];
218     int x,y,z,T;
219     scanf("%d%d",&n,&m);
220     for(int i=1;i<=n;i++)
221         scanf("%d",&s[i]);
222     build(1,1,n);
223     for(int i=1;i<=m;i++)
224     {
225         scanf("%s",ss);
226         if(ss[0]==Q)
227         {
228             scanf("%d%d%d",&x,&y,&z);
229             printf("%d\n",QUEST(x,y,z));
230         }
231         else
232         {
233             scanf("%d%d",&x,&y);
234             change(1,x,y);
235             s[x]=y;
236         }
237     }
238 }
BZOJ 1901

 

BZOJ 1901 Dynamic Rankings