真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[BZOJ 1901]Dynamic Rankings

[BZOJ 1901]Dynamic Rankings

题目

给定一个含有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≤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
m,n≤10000

OUTPUT

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

SAMPLE

INPUT

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

OUTPUT

3

6

解题报告

打了一下午的静态主席树,终于进阶到动态的了= =

树状数组套一个主席树

我们想,主席树是通过前缀和来维护信息的,我们一修改就全都乱了,所以我们需要一个数据结构来维护前缀和,很自然的就想到了树状数组

我们在修改时,利用树状数组,将其原来所产生的影响清除,然后进行更新,就可以对主席树进行动态操作了

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 using namespace std;
  6 inline int read(){
  7     int sum(0);
  8     char ch(getchar());
  9     for(;ch<'0'||ch>'9';ch=getchar());
 10     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 11     return sum;
 12 }
 13 int n,m;
 14 int tot,size,cnt;
 15 int v[10005],num[20005],has[20005];
 16 int rt[10005],sum[2500005],lch[2500005],rch[2500005];
 17 int A[10005],B[10005],K[10005];
 18 bool flag[10005];
 19 int a,b,L[30],R[30];
 20 char op[2];
 21 inline int lowbit(int x){
 22     return x&-x;
 23 }
 24 inline int find(int x){
 25     int l(1),r(size),mid;
 26     while(l<=r){
 27         mid=(l+r)>>1;
 28         if(has[mid]<x)
 29             l=mid+1;
 30         else
 31             r=mid-1;
 32     }
 33     return l;
 34     //return lower_bound(has+1,has+size+1,x)-has;
 35 }
 36 inline void update(int &x,int las,int pos,int w,int l,int r){
 37     x=++cnt;
 38     lch[x]=lch[las];
 39     rch[x]=rch[las];
 40     sum[x]=sum[las]+w;
 41     if(l==r)
 42         return;
 43     int mid((l+r)>>1);
 44     if(pos<=mid)
 45         update(lch[x],lch[las],pos,w,l,mid);
 46     else
 47         update(rch[x],rch[las],pos,w,mid+1,r);
 48 }
 49 inline int query(int l,int r,int k){
 50     if(l==r)
 51         return l;
 52     int suml(0),sumr(0),mid((l+r)>>1);
 53     for(int i=1;i<=a;++i)suml+=sum[lch[L[i]]];
 54     for(int i=1;i<=b;++i)sumr+=sum[lch[R[i]]];
 55     if(sumr-suml>=k){
 56         for(int i=1;i<=a;++i)L[i]=lch[L[i]];
 57         for(int i=1;i<=b;++i)R[i]=lch[R[i]];
 58         return query(l,mid,k);
 59     }
 60     else{
 61         for(int i=1;i<=a;++i)L[i]=rch[L[i]];
 62         for(int i=1;i<=b;++i)R[i]=rch[R[i]];
 63         return query(mid+1,r,k-(sumr-suml));
 64     }
 65 }
 66 int main(){
 67     n=read(),m=read();
 68     for(int i=1;i<=n;++i){
 69         v[i]=read();
 70         num[++tot]=v[i];
 71     }
 72     for(int i=1;i<=m;++i){
 73         scanf("%s",op);
 74         if(op[0]=='Q'){
 75             flag[i]=1;
 76             A[i]=read();
 77             B[i]=read();
 78             K[i]=read();
 79         }
 80         else{
 81             A[i]=read();
 82             B[i]=read();
 83             num[++tot]=B[i];
 84         }
 85     }
 86     sort(num+1,num+tot+1);
 87     has[++size]=num[1];
 88     for(int i=2;i<=tot;++i)
 89         if(num[i]!=num[i-1])
 90             has[++size]=num[i];
 91     for(int i=1;i<=n;++i){
 92         int tmp(find(v[i]));
 93         for(int j=i;j<=n;j+=lowbit(j))
 94             update(rt[j],rt[j],tmp,1,1,size);
 95     }
 96     for(int i=1;i<=m;++i){
 97         if(flag[i]){
 98             a=b=0;
 99             --A[i];
100             for(int j=A[i];j>0;j-=lowbit(j))
101                 L[++a]=rt[j];
102             for(int j=B[i];j>0;j-=lowbit(j))
103                 R[++b]=rt[j];
104             printf("%d\n",has[query(1,size,K[i])]);
105         }
106         else{
107             int tmp(find(v[A[i]]));
108             for(int j=A[i];j<=n;j+=lowbit(j))
109                 update(rt[j],rt[j],tmp,-1,1,size);
110             v[A[i]]=B[i];
111             tmp=find(B[i]);
112             for(int j=A[i];j<=n;j+=lowbit(j))
113                 update(rt[j],rt[j],tmp,1,1,size);
114         }
115     }
116 }
View Code

 

posted @ 2017-09-23 21:01  Hzoi_Mafia  阅读(222)  评论(0编辑  收藏  举报
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神