# 【带修改的主席树】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  阅读(...)  评论(...编辑  收藏