【带修改的主席树】BZOJ1901-Dynamic Rankings

稍后整理笔记。这题数据范围好像有点问题?

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<algorithm>
  6 #define lson l,m
  7 #define rson m+1,r
  8 using namespace std;
  9 const int MAXN=60000+50;
 10 int n,q,tot,m,d;
 11 struct node
 12 {
 13     int l,r,k,Q;
 14 }op[MAXN];
 15 int a[MAXN<<1],hash[MAXN<<1],T[MAXN<<1],S[MAXN<<1],use[MAXN<<1];
 16 int L[MAXN<<5],R[MAXN<<5],sum[MAXN<<5];
 17 
 18 int lowbit(int x)
 19 {
 20     return (x&(-x));
 21 }
 22 
 23 int build(int l,int r)
 24 {
 25     int rt=++tot;
 26     sum[rt]=0;
 27     if (l!=r)
 28     {
 29         int m=(l+r)>>1;
 30         L[rt]=build(lson);
 31         R[rt]=build(rson);
 32     }
 33     return rt;
 34 }
 35 
 36 int update(int pre,int l,int r,int x,int op)
 37 {
 38     int rt=++tot;
 39     L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+op;
 40     if (l<r)
 41     {
 42         int m=(l+r)>>1;
 43         if (x<=m) L[rt]=update(L[pre],lson,x,op);
 44             else R[rt]=update(R[pre],rson,x,op); 
 45     } 
 46     return rt;
 47 }
 48 
 49 int Sum(int x)
 50 {
 51     int ret=0;
 52     while (x>0)
 53     {
 54         ret+=sum[L[use[x]]];
 55         x-=lowbit(x);
 56     }
 57     return ret;
 58 }
 59 
 60 int query(int Sl,int Sr,int Tl,int Tr,int l,int r,int k)
 61 {
 62     if (l==r) return l;
 63     int m=(l+r)>>1;
 64     int tmp=Sum(Sr)-Sum(Sl)+sum[L[Tr]]-sum[L[Tl]];
 65     if (tmp>=k)
 66     {
 67         for (int i=Sl;i;i-=lowbit(i)) use[i]=L[use[i]];
 68         for (int i=Sr;i;i-=lowbit(i)) use[i]=L[use[i]];
 69         return query(Sl,Sr,L[Tl],L[Tr],lson,k);
 70     }
 71     else
 72     {
 73         for (int i=Sl;i;i-=lowbit(i)) use[i]=R[use[i]];
 74         for (int i=Sr;i;i-=lowbit(i)) use[i]=R[use[i]];
 75         return query(Sl,Sr,R[Tl],R[Tr],rson,k-tmp);
 76     }
 77 } 
 78 
 79 void modify(int x,int p,int delta)
 80 {
 81     while (x<=n)
 82     {
 83         S[x]=update(S[x],1,d,p,delta);
 84         x+=lowbit(x);
 85     }
 86 }
 87 
 88 void init()
 89 {
 90     tot=0;
 91     m=0;
 92     d=0;
 93     scanf("%d%d",&n,&q);
 94     for (int i=1;i<=n;i++) scanf("%d",&a[i]),hash[++m]=a[i];
 95     for (int i=0;i<q;i++)
 96     {
 97         char s[10];
 98         scanf("%s",s);
 99         if (s[0]=='Q')    scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k),op[i].Q=1;
100             else 
101             {
102                 scanf("%d%d",&op[i].l,&op[i].r);
103                 op[i].Q=0;
104                 hash[++m]=op[i].r;
105             }
106     }
107     /*因为修改后的数可能不在初始几个数的范围内,故要先输入完查询*/ 
108     
109     sort(hash+1,hash+m+1);
110     d=unique(hash+1,hash+1+m)-hash-1;
111     
112     T[0]=build(1,d);//T表示每一步T树的树根
113     for (int i=1;i<=n;i++)
114     {
115         int x=lower_bound(hash+1,hash+d+1,a[i])-hash;
116         T[i]=update(T[i-1],1,d,x,1);
117     }
118     
119     for (int i=1;i<=n;i++) S[i]=T[0];
120 }
121 
122 void solve()
123 {
124   
125     for (int i=0;i<q;i++)
126     {
127         if (op[i].Q)
128         {
129             for (int j=op[i].l-1;j;j-=lowbit(j)) use[j]=S[j];
130             for (int j=op[i].r;j;j-=lowbit(j)) use[j]=S[j];
131             int ans=query(op[i].l-1,op[i].r,T[op[i].l-1],T[op[i].r],1,d,op[i].k);
132             printf("%d\n",hash[ans]);
133         }
134         else
135         {
136             int x=lower_bound(hash+1,hash+d+1,a[op[i].l])-hash;
137             int y=lower_bound(hash+1,hash+d+1,op[i].r)-hash;
138             modify(op[i].l,x,-1);
139             modify(op[i].l,y,1);
140             a[op[i].l] =op[i].r;
141         }
142     }
143 }
144 
145 int main()
146 {
147     init();
148     solve();
149     return 0;
150 }

 

posted @ 2016-08-12 09:53  iiyiyi  阅读(199)  评论(0编辑  收藏  举报