bzoj 1901: Zju2112 Dynamic Rankings

新姿势,,这真是神题啊,用这道题研究的线段树套平衡树,然后又围观了树状数组套主席树,各种涨姿势2333

说一下树状数组套主席树吧。

对于树状数组的每个节点维护一个主席树,然后查询就是把普通主席树的查询改成在树状数组上,每一次查询lowbit,加起来就好了2333,修改也是一样的。

  1 #include<bits/stdc++.h>
  2 #define N 100005
  3 #define M 10000005
  4 #define LL long long
  5 #define inf 0x3f3f3f3f
  6 #define lowbit(x) x&(-x) 
  7 using namespace std;               //(zoj2112)
  8 inline int ra()
  9 {
 10     int x=0,f=1; char ch=getchar();
 11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 13     return x*f;
 14 }
 15 int n,m,tot,top,sz;
 16 int v[10001],num[20001],hash[20001];
 17 int flag[10001],A[10001],B[10001],K[10001],root[10001];
 18 int sum[2200001],ls[2200001],rs[2200001];
 19 int L[30],R[30],a,b;
 20 int find(int x)
 21 {
 22     int l=1,r=tot,mid;
 23     while (l<=r)
 24     {
 25         int mid=l+r>>1;
 26         if (hash[mid]<x) l=mid+1;
 27         else r=mid-1;
 28     }
 29     return l;
 30 }
 31 void update(int last, int l, int r, int &rt, int w, int x)
 32 {
 33     rt=++sz; 
 34     sum[rt]=sum[last]+x;
 35     if (l==r) return;
 36     ls[rt]=ls[last]; rs[rt]=rs[last];
 37     int mid=l+r>>1;
 38     if (w<=mid) update(ls[last],l,mid,ls[rt],w,x);
 39     else update(rs[last],mid+1,r,rs[rt],w,x);
 40 }
 41 int query(int l, int r, int k)
 42 {
 43     if (l==r) return l;
 44     int suml=0,sumr=0;
 45     for (int i=1; i<=a; i++) suml+=sum[ls[L[i]]];
 46     for (int i=1; i<=b; i++) sumr+=sum[ls[R[i]]];
 47     int mid=l+r>>1;
 48     if (sumr-suml>=k)
 49     {
 50         for (int i=1; i<=a; i++) L[i]=ls[L[i]];
 51         for (int i=1; i<=b; i++) R[i]=ls[R[i]];
 52         return query(l,mid,k);
 53     }
 54     else
 55     {
 56         for (int i=1; i<=a; i++) L[i]=rs[L[i]];
 57         for (int i=1; i<=b; i++) R[i]=rs[R[i]];
 58         return query(mid+1,r,k-(sumr-suml));
 59     }
 60 }
 61 int main()
 62 {
 63     n=ra(); m=ra();
 64     for (int i=1; i<=n; i++)
 65         v[i]=ra(),num[++top]=v[i];
 66     for (int i=1; i<=m; i++)
 67     {
 68         char s[3]; scanf("%s",s);
 69         A[i]=ra(); B[i]=ra();
 70         if (s[0]=='Q') K[i]=ra(),flag[i]=1;
 71             else num[++top]=B[i];
 72     }
 73     sort(num+1,num+top+1);
 74     hash[++tot]=num[1];
 75     for (int i=2; i<=top; i++)
 76         if (num[i]!=num[i-1])
 77             hash[++tot]=num[i];
 78     for (int i=1; i<=n; i++)
 79     {
 80         int t=find(v[i]);
 81         for (int j=i; j<=n; j+=lowbit(j))
 82             update(root[j],1,tot,root[j],t,1);
 83     }
 84     for (int i=1; i<=m; i++)
 85         if (flag[i])
 86         {
 87             a=0,b=0; A[i]--;
 88             for (int j=A[i]; j>0; j-=lowbit(j))
 89                 L[++a]=root[j];
 90             for (int j=B[i]; j>0; j-=lowbit(j))
 91                 R[++b]=root[j];
 92             printf("%d\n",hash[query(1,tot,K[i])]);
 93         }
 94         else
 95         {
 96             int t=find(v[A[i]]);
 97             for (int j=A[i]; j<=n; j+=lowbit(j))
 98                 update(root[j],1,tot,root[j],t,-1);
 99             v[A[i]]=B[i];
100             t=find(B[i]);
101             for (int j=A[i]; j<=n; j+=lowbit(j))
102                 update(root[j],1,tot,root[j],t,1);
103         }
104         return 0;
105 }

 

posted @ 2017-02-21 21:16  ws_ccd  阅读(161)  评论(0编辑  收藏  举报