【ZJOI2017 Round1练习&BZOJ4765】D1T3 普通计算姬(主席树,分块)

题意:

思路:分块

使用树状数组维护sum[i]的前缀和

使用主席树维护root到u的路径上点的编号出现的个数

每次操作如果是修改就加入队列

如果是询问,考虑块内操作对询问的影响,每次在x点加上y会使x到root的点sum都加上y

每根号n次操作就暴力重构一次,清空队列并求出新的sum[i]的前缀和

 

  1 var t:array[0..3100000]of record
  2                            l,r:longint;
  3                            s:int64;
  4                           end;
  5     sum,bit:array[0..310000]of int64;
  6     stk:array[0..310000,1..2]of longint;
  7     head,vet,next,fa,a:array[0..310000]of longint;
  8     root:array[0..1100000]of longint;
  9     n,m,x,y,i,j,top,tot,cnt,kuai,rt,op:longint;
 10     ans,tmp:int64;
 11 
 12 procedure add(a,b:longint);
 13 begin
 14  inc(tot);
 15  next[tot]:=head[a];
 16  vet[tot]:=b;
 17  head[a]:=tot;
 18 end;
 19 
 20 procedure pushup(p:longint);
 21 begin
 22  t[p].s:=t[t[p].l].s+t[t[p].r].s;
 23 end;
 24 
 25 procedure update(l,r,x:longint;var p:longint);
 26 var mid:longint;
 27 begin
 28  inc(cnt); t[cnt]:=t[p];
 29  p:=cnt; inc(t[p].s);
 30  if l=r then exit;
 31  mid:=(l+r)>>1;
 32  if x<=mid then update(l,mid,x,t[p].l)
 33   else update(mid+1,r,x,t[p].r);
 34  pushup(p);
 35 end;
 36 
 37 function query(l,r,x,y,p:longint):int64;
 38 var mid:longint;
 39 begin
 40  if (l>=x)and(r<=y) then exit(t[p].s);
 41  mid:=(l+r)>>1;
 42  query:=0;
 43  if x<=mid then query:=query+query(l,mid,x,y,t[p].l);
 44  if y>mid then query:=query+query(mid+1,r,x,y,t[p].r);
 45  pushup(p);
 46 end;
 47 
 48 procedure dfs1(u:longint);
 49 var e,v:longint;
 50 begin
 51  root[u]:=root[fa[u]];
 52  update(1,n,u,root[u]);
 53  e:=head[u];
 54  while e<>0 do
 55  begin
 56   v:=vet[e];
 57   if v<>fa[u] then
 58   begin
 59    fa[v]:=u;
 60    dfs1(v);
 61   end;
 62   e:=next[e];
 63  end;
 64 end;
 65 
 66 procedure dfs2(u:longint);
 67 var e,v:longint;
 68 begin
 69  sum[u]:=a[u];
 70  e:=head[u];
 71  while e<>0 do
 72  begin
 73   v:=vet[e];
 74   if v<>fa[u] then
 75   begin
 76    dfs2(v);
 77    sum[u]:=sum[u]+sum[v];
 78   end;
 79   e:=next[e];
 80  end;
 81 end;
 82 
 83 function lowbit(x:longint):longint;
 84 begin
 85  exit(x and (-x));
 86 end;
 87 
 88 procedure addbit(x:longint;y:int64);
 89 begin
 90  while x<=n do
 91  begin
 92   bit[x]:=bit[x]+y;
 93   x:=x+lowbit(x);
 94  end;
 95 end;
 96 
 97 function querybit(x,y:longint):int64;
 98 var k:longint;
 99 begin
100  k:=y;
101  querybit:=0;
102  while k>0 do
103  begin
104   querybit:=querybit+bit[k];
105   k:=k-lowbit(k);
106  end;
107  k:=x-1;
108  while k>0 do
109  begin
110   querybit:=querybit-bit[k];
111   k:=k-lowbit(k);
112  end;
113 end;
114 
115 procedure build;
116 var i:longint;
117 begin
118  for i:=1 to n do bit[i]:=0;
119  for i:=1 to n do addbit(i,sum[i]);
120 end;
121 
122 begin
123  assign(input,'common.in'); reset(input);
124  assign(output,'common.out'); rewrite(output);
125  readln(n,m);
126  kuai:=500;
127  for i:=1 to n do read(a[i]);
128  for i:=1 to n do
129  begin
130   readln(x,y);
131   if x=0 then rt:=y
132    else
133    begin
134     add(x,y);
135     add(y,x);
136    end;
137  end;
138  dfs1(rt);
139  fillchar(head,sizeof(head),0);
140  tot:=0;
141  for i:=1 to n do
142   if i<>rt then add(fa[i],i);
143  dfs2(rt);
144  build;
145 
146  for i:=1 to m do
147  begin
148   readln(op,x,y);
149   if op=1 then
150   begin
151    inc(top); stk[top,1]:=x; stk[top,2]:=y-a[x];
152    a[x]:=y;
153   end
154    else
155    begin
156     ans:=querybit(x,y);
157     for j:=1 to top do
158     begin
159      tmp:=query(1,n,x,y,root[stk[j,1]]);
160      ans:=ans+stk[j,2]*tmp;
161     end;
162     writeln(ans);
163    end;
164   if i mod kuai=0 then
165   begin
166    top:=0;
167    dfs2(rt);
168    build;
169   end;
170  end;
171  close(input);
172  close(output);
173 end.

 

posted on 2017-03-02 18:15  myx12345  阅读(200)  评论(0编辑  收藏  举报

导航