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

时间: 2024-10-12 11:11:00

BZOJ 1901 Dynamic Rankings的相关文章

[BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log n). 代码 树状数组套线段树 #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> usin

BZOJ 1901 Dynamic Rankings 主席树

题目大意:可修改的区间第k小 这个主席树卡了我两天...切掉Count On A Tree 之后我就一直认为带修改的主席树是树状数组套可持久化线段树...其实我被误导了... 尼玛带修改的主席树和可持久化线段树毛关系都木有啊!!! 那就是动态的权值线段树啊啊啊啊啊啊啊!!! 好吧这里给不明白主席树的孩纸一些简介: 1.外层树状数组 2.里层线段树 3.线段树动态开节点.仅此而已.和可持久化完全没关系. 4.一个点上的线段树和其他版本毛关系都没有. 5.正常按照普通的树套树往里插就行了. 7.询问

BZOJ 1901 Dynamic Rankings 树董事长

标题效果:间隔可以改变k少 我的两个天树牌主席... 隔断Count On A Tree 之后我一直认为,随着树的主席的变化是分域林木覆盖率可持久段树. .. 事实上,我是误导... 尼可持久化线段树毛关系都木有啊!! ! 那就是动态的权值线段树啊啊啊啊啊啊啊!!! 好吧这里给不明确主席树的孩纸一些简单介绍: 1.外层树状数组 2.里层线段树 3.线段树动态开节点.仅此而已.和可持久化全然没关系. 4.一个点上的线段树和其它版本号毛关系都没有. 5.正常依照普通的树套树往里插即可了. 7.询问时

HYSBZ 1901 Dynamic Rankings 树状数组套主席树

ZOJ上面这题内存限制太严格,裸的树套树主席树搞法过不去,BZOJ上面这个放的比较松,可以过. 其实就是利用树状数组维护n颗主席树,然后利用前缀和性质求解第k大. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include

bzoj 1901: Zju2112 Dynamic Rankings(树套树)

1901: Zju2112 Dynamic Rankings 经典的带修改求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,而且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过不了. 思路很简单,用线段树维护区间,用splay维护区间内的权值,然后询问的时候,二分答案key,然后在区间内找小于key的数有多少个. 贴上模板: #include<stdio.h> #include<string.h> #include<algorithm> #def

BZOJ 1901: Zju2112 Dynamic Rankings 区间k大 带修改 在线 线段树套平衡树

之前写线段树套splay数组版..写了6.2k..然后弃疗了.现在发现还是很水的..嘎嘎.. zju过不了,超时. upd:才发现zju是多组数据..TLE一版才发现.然后改了,MLE...手写内存池..尼玛终于过了..附zju2112代码于后. bzoj倒是过了,1A的感觉还是很爽的..可是时间不好看..这就是所谓\(O(nlog^3n)\)的复杂度的可怜之处么? 写挂的地方: insert一定要是传地址指针进去. delete时先把地址指针delete掉,最后把是地址指针指向左儿子or右儿子

Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap

1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6471  Solved: 2697[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

BZOJ 1901: Zju2112 Dynamic Rankings( 树状数组套主席树 )

裸的带修改主席树.. 之前用BIT套Splay( http://www.cnblogs.com/JSZX11556/p/4625552.html )A过..但是还是线段树好写...而且快(常数比平衡树小). 时空复杂度是O(Nlog(N)+Mlog^2(N)) ------------------------------------------------------------------------- #include<cstdio> #include<cstring> #in

bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB 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(1≤