随笔 - 540  文章 - 0 评论 - 39 trackbacks - 0

带修改的主席树
怎么搞呢,由于主席树满足减法性质,且维护的是前缀信息,所以我们不难想到套一个树状数组来优化
也很好理解,对于第i个位置,修改对后面的lowbit+都修改,求和lowbit-都求和
由于修改要修改logn个树,每棵树都要开辟logS个节点,所以空间复杂度是两个log值得注意
有修改还要将修改成的数一并离散化,所以带修改的主席树是一个离线数据结构

  1 type node=record
  2        wh:char;
  3        l,r,x:longint;
  4      end;
  5      point=record
  6        l,r,s:longint;
  7      end;
  8 
  9 var q:array[0..10010] of node;
 10     tree:array[0..3000010] of point;
 11     h,c,a,w,sa,d1,d2:array[0..20010] of longint;
 12     j,s,p,last,t,t1,t2,x,i,n,m:longint;
 13 
 14 function lowbit(x:longint):longint;
 15   begin
 16     exit(x and (-x));
 17   end;
 18 
 19 procedure swap(var a,b:longint);
 20   var c:longint;
 21   begin
 22     c:=a;
 23     a:=b;
 24     b:=c;
 25   end;
 26 
 27 function find(x:longint):longint;
 28   var l,r,m:longint;
 29   begin
 30     l:=1;
 31     r:=p;
 32     while l<=r do
 33     begin
 34       m:=(l+r) shr 1;
 35       if sa[m]=x then exit(m);
 36       if sa[m]>x then r:=m-1 else l:=m+1;
 37     end;
 38   end;
 39 
 40 procedure sort(l,r: longint);
 41   var i,j,x,y: longint;
 42   begin
 43     i:=l;
 44     j:=r;
 45     x:=a[(l+r) div 2];
 46     repeat
 47       while a[i]<x do inc(i);
 48       while x<a[j] do dec(j);
 49       if not(i>j) then
 50       begin
 51         swap(a[i],a[j]);
 52         inc(i);
 53         j:=j-1;
 54       end;
 55     until i>j;
 56     if l<j then sort(l,j);
 57     if i<r then sort(i,r);
 58  end;
 59 
 60 procedure update(i:longint);
 61   begin
 62     tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s;
 63   end;
 64 
 65 function build(l,r:longint):longint;
 66   var m,q:longint;
 67   begin
 68     inc(t);
 69     if l=r then exit(t)
 70     else begin
 71       q:=t;
 72       m:=(l+r) shr 1;
 73       tree[q].l:=build(l,m);
 74       tree[q].r:=build(m+1,r);
 75       exit(q);
 76     end;
 77   end;
 78 
 79 function add(l,r,y,z:longint):longint;
 80   var m,q:longint;
 81   begin
 82     inc(t);
 83     if l=r then
 84     begin
 85       tree[t].s:=tree[last].s+z;
 86       exit(t);
 87     end
 88     else begin
 89       q:=t;
 90       m:=(l+r) shr 1;
 91       if y<=m then
 92       begin
 93         tree[q].r:=tree[last].r;
 94         last:=tree[last].l;
 95         tree[q].l:=add(l,m,y,z);
 96       end
 97       else begin
 98         tree[q].l:=tree[last].l;
 99         last:=tree[last].r;
100         tree[q].r:=add(m+1,r,y,z);
101       end;
102       update(q);
103       exit(q);
104     end;
105   end;
106 
107 procedure insert(x,y,z:longint);
108   begin
109     while x<=n do
110     begin
111       last:=h[x];
112       h[x]:=add(1,p,y,z);
113       x:=x+lowbit(x);
114     end;
115   end;
116 
117 function getans(l,r,x:longint):longint;
118   var m,i,s1,s2,j:longint;
119   begin
120     if l=r then exit(sa[l])
121     else begin
122       m:=(l+r) shr 1;
123       s1:=0;
124       s2:=0;
125       for i:=1 to t1 do
126       begin
127         j:=tree[d1[i]].l;
128         s1:=s1+tree[j].s;
129       end;
130       for i:=1 to t2 do
131       begin
132         j:=tree[d2[i]].l;
133         s2:=s2+tree[j].s;
134       end;
135       if s2-s1>=x then
136       begin
137         for i:=1 to t1 do
138           d1[i]:=tree[d1[i]].l;
139         for i:=1 to t2 do
140           d2[i]:=tree[d2[i]].l;
141         exit(getans(l,m,x));
142       end
143       else begin
144         for i:=1 to t1 do
145           d1[i]:=tree[d1[i]].r;
146         for i:=1 to t2 do
147           d2[i]:=tree[d2[i]].r;
148         x:=x-(s2-s1);
149         exit(getans(m+1,r,x));
150       end;
151     end;
152   end;
153 
154 function ask(l,r,x:longint):longint;
155   var y:longint;
156   begin
157     t1:=0;
158     t2:=0;
159     y:=l-1;
160     while y>0 do   //提取区间
161     begin
162       inc(t1);
163       d1[t1]:=h[y];
164       y:=y-lowbit(y);
165     end;
166     y:=r;
167     while y>0 do
168     begin
169       inc(t2);
170       d2[t2]:=h[y];
171       y:=y-lowbit(y);
172     end;
173     exit(getans(1,p,x));
174   end;
175 
176 begin
177   readln(n,m);
178   s:=n;
179   for i:=1 to n do
180   begin
181     read(c[i]);
182     a[i]:=c[i];
183   end;
184   readln;
185   for i:=1 to m do
186   begin
187     read(q[i].wh);
188     if q[i].wh='Q' then
189       readln(q[i].l,q[i].r,q[i].x)
190     else begin
191       readln(q[i].l,q[i].x);
192       inc(s);
193       a[s]:=q[i].x;
194     end;
195   end;
196   sort(1,s);
197   p:=1;
198   sa[1]:=a[1];
199   for i:=2 to s do  //离散化
200     if a[i]<>a[i-1] then
201     begin
202       inc(p);
203       sa[p]:=a[i];
204     end;
205 
206   h[0]:=build(1,p);
207   for i:=1 to n do
208   begin
209     w[i]:=find(c[i]);
210     insert(i,w[i],1);
211   end;
212   for i:=1 to m do
213   begin
214     if q[i].wh='Q' then
215       writeln(ask(q[i].l,q[i].r,q[i].x))
216     else begin
217       x:=find(q[i].x);
218       insert(q[i].l,w[q[i].l],-1);  //修改的两步
219       insert(q[i].l,x,1);
220       w[q[i].l]:=x;
221     end;
222   end;
223 end.
View Code

 

posted on 2014-12-02 21:51  acphile  阅读(...)  评论(...编辑  收藏