【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.
null