BZOJ 1901 Dynamic Rankings
题面:
1901: Zju2112 Dynamic Rankings
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
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 }