【bzoj 1901】Zju2112 Dynamic Rankings

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≤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

Sample Output

3
6

 

带修改的整体二分……整体二分不会改变操作顺序,把修改也加进操作就可以了√

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 using namespace std;
 6 const int N=5e4+5;
 7 const int inf=1e9;
 8 int n,m,cnt,qid,id,temp,x[N],ans[N],tr[N];
 9 bool f[N];
10 char ch[5];
11 struct node{int op,l,r,k,num;}a[N],tmp[N];
12 int lowbit(int x){return x&(-x);}
13 void insert(int x,int c){while(x<=n)tr[x]+=c,x+=lowbit(x);}
14 int query(int x){int ans=0;while(x)ans+=tr[x],x-=lowbit(x);return ans;}
15 int read()
16 {
17     int x=0,f=1;char c=getchar();
18     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
19     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
20     return x*f;
21 }
22 void work(int ql,int qr,int L,int R)
23 {
24     if(ql>qr||L>R)return;
25     if(L==R){for(int i=ql;i<=qr;i++)if(a[i].op)ans[a[i].num]=L;return;}
26     int mid=(L+R)>>1,h1=ql,h2=ql;
27     for(int i=ql;i<=qr;i++)
28         if(a[i].op)
29         {
30             temp=query(a[i].r)-query(a[i].l-1);
31             if(temp>=a[i].k)f[i]=true,h2++;
32             else f[i]=false,a[i].k-=temp;
33         }
34         else
35         {
36             if(a[i].num<=mid)f[i]=true,h2++,insert(a[i].l,a[i].k);
37             else f[i]=false;
38         }
39     for(int i=ql;i<=qr;i++)if((!a[i].op)&&f[i])insert(a[i].l,-a[i].k);
40     for(int i=ql;i<=qr;i++)
41         if(f[i])tmp[h1++]=a[i];
42         else tmp[h2++]=a[i];
43     for(int i=ql;i<=qr;i++)a[i]=tmp[i];
44     work(ql,h1-1,L,mid);work(h1,qr,mid+1,R);
45 }
46 int main()
47 {
48     n=read();m=read();
49     for(int i=1;i<=n;i++)x[i]=read(),a[++cnt]=(node){0,i,0,1,x[i]};
50     for(int i=1;i<=m;i++)
51     {
52         scanf("%s",ch+1);
53         if(ch[1]=='Q')
54         {
55             a[++cnt].op=1;a[cnt].num=++qid;
56             a[cnt].l=read();a[cnt].r=read();a[cnt].k=read();
57         }
58         else
59         {
60             id=read();temp=read();
61             a[++cnt]=(node){0,id,0,-1,x[id]};
62             a[++cnt]=(node){0,id,0,1,x[id]=temp};
63         }
64     }
65     work(1,cnt,-inf,inf);
66     for(int i=1;i<=qid;i++)printf("%d\n",ans[i]);
67     return 0;
68 }
View Code

 

带修改的主席树……外面要套个树状数组。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 using namespace std;
 6 const int N=2e4+5;
 7 int n,m,cnt,tot,id,tx,ty;
 8 int A[N],B[N],C[N],a[N],tmp[N],rt[N],xx[N],yy[N];
 9 int lc[N*200],rc[N*200],sum[N*200];
10 char op[3];
11 int read()
12 {
13     int x=0,f=1;char c=getchar();
14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
16     return x*f;
17 }
18 int lowbit(int x){return x&(-x);}
19 void ins(int& x,int last,int L,int R,int num,int c)
20 {
21     x=++tot;lc[x]=lc[last];rc[x]=rc[last];sum[x]=sum[last]+c;
22     if(L==R)return;int mid=(L+R)>>1;
23     if(num<=mid)ins(lc[x],lc[last],L,mid,num,c);
24     else ins(rc[x],rc[last],mid+1,R,num,c);
25 }
26 void add(int x,int c)
27 {
28     id=lower_bound(tmp+1,tmp+cnt+1,a[x])-tmp;
29     for(int i=x;i<=n;i+=lowbit(i))ins(rt[i],rt[i],1,cnt,id,c);
30 }
31 int query(int L,int R,int num)
32 {
33     if(L==R)return L;
34     int ans=0,mid=(L+R)>>1;
35     for(int i=1;i<=tx;i++)ans-=sum[lc[xx[i]]];
36     for(int i=1;i<=ty;i++)ans+=sum[lc[yy[i]]];
37     if(num<=ans)
38     {
39         for(int i=1;i<=tx;i++)xx[i]=lc[xx[i]];
40         for(int i=1;i<=ty;i++)yy[i]=lc[yy[i]];
41         return query(L,mid,num);
42     }
43     else
44     {
45         for(int i=1;i<=tx;i++)xx[i]=rc[xx[i]];
46         for(int i=1;i<=ty;i++)yy[i]=rc[yy[i]];
47         return query(mid+1,R,num-ans);
48     }
49 }
50 int main()
51 {
52     n=read();m=read();cnt=n;
53     for(int i=1;i<=n;i++)tmp[i]=a[i]=read();
54     for(int i=1;i<=m;i++)
55     {
56         scanf("%s",op+1);
57         A[i]=read();B[i]=read();
58         if(op[1]=='Q')C[i]=read();
59         else tmp[++cnt]=B[i];
60     }
61     sort(tmp+1,tmp+cnt+1);
62     cnt=unique(tmp+1,tmp+cnt+1)-tmp-1;
63     for(int i=1;i<=n;i++)add(i,1);
64     for(int i=1;i<=m;i++)
65         if(C[i])
66         {
67             tx=ty=0;
68             for(int j=A[i]-1;j;j-=lowbit(j))xx[++tx]=rt[j];
69             for(int j=B[i];j;j-=lowbit(j))yy[++ty]=rt[j];
70             printf("%d\n",tmp[query(1,cnt,C[i])]);
71         }
72         else add(A[i],-1),a[A[i]]=B[i],add(A[i],1);
73     return 0;
74 }
View Code

 

posted @ 2017-12-25 20:37  Zsnuo  阅读(...)  评论(...编辑  收藏