解题思路:
开始写了个LCT后来发现是错的QAQ
正解是动态点分治。
剩下的部分和幻想乡那道题就一样了。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll spc<<1 5 #define rrr spc<<1|1 6 typedef long long lnt; 7 const int N=200010; 8 struct trnt{ 9 lnt sum; 10 lnt lzt; 11 }tr[N<<2]; 12 struct pnt{ 13 int hd; 14 int fa; 15 int dp; 16 int tp; 17 int ft; 18 int ind; 19 int oud; 20 int wgt; 21 int mxs; 22 lnt val; 23 lnt sum; 24 lnt Sum; 25 int eind; 26 lnt diss; 27 lnt disf; 28 bool vis; 29 }p[N]; 30 struct ent{ 31 int twd; 32 int lst; 33 }e[N<<1]; 34 int rt; 35 int n,m; 36 int cnt; 37 int dfn; 38 int tdn; 39 int root; 40 int size; 41 int maxsize; 42 int lg[N<<2]; 43 int eula[N<<2][21]; 44 lnt w; 45 lnt V; 46 lnt val[N]; 47 void pushup(int spc) 48 { 49 tr[spc].sum=tr[lll].sum+tr[rrr].sum; 50 return ; 51 } 52 void add(int spc,int l,int r,lnt v) 53 { 54 tr[spc].lzt+=v; 55 tr[spc].sum+=v*(r-l+1); 56 return ; 57 } 58 void pushdown(int l,int mid,int r,int spc) 59 { 60 if(tr[spc].lzt) 61 { 62 lnt v=tr[spc].lzt; 63 add(lll,l,mid,v); 64 add(rrr,mid+1,r,v); 65 tr[spc].lzt=0; 66 } 67 return ; 68 } 69 void build(int l,int r,int spc) 70 { 71 if(l==r) 72 { 73 tr[spc].sum=val[l]; 74 return ; 75 } 76 int mid=(l+r)>>1; 77 build(l,mid,lll); 78 build(mid+1,r,rrr); 79 pushup(spc); 80 return ; 81 } 82 void update(int l,int r,int ll,int rr,int spc,lnt v) 83 { 84 if(ll>r||l>rr) 85 return ; 86 if(ll<=l&&r<=rr) 87 { 88 add(spc,l,r,v); 89 return ; 90 } 91 int mid=(l+r)>>1; 92 pushdown(l,mid,r,spc); 93 update(l,mid,ll,rr,lll,v); 94 update(mid+1,r,ll,rr,rrr,v); 95 pushup(spc); 96 return ; 97 } 98 lnt query(int l,int r,int ll,int rr,int spc) 99 { 100 if(ll>r||l>rr) 101 return 0; 102 if(ll<=l&&r<=rr) 103 return tr[spc].sum; 104 int mid=(l+r)>>1; 105 pushdown(l,mid,r,spc); 106 return query(l,mid,ll,rr,lll)+query(mid+1,r,ll,rr,rrr); 107 } 108 void ade(int f,int t) 109 { 110 cnt++; 111 e[cnt].twd=t; 112 e[cnt].lst=p[f].hd; 113 p[f].hd=cnt; 114 return ; 115 } 116 void E_dfs(int x,int f) 117 { 118 eula[++dfn][0]=x; 119 p[x].eind=dfn; 120 p[x].dp=p[f].dp+1; 121 p[x].ft=f; 122 p[x].wgt=1; 123 int maxs=-1; 124 for(int i=p[x].hd;i;i=e[i].lst) 125 { 126 int to=e[i].twd; 127 if(to==f) 128 continue; 129 E_dfs(to,x); 130 p[x].wgt+=p[to].wgt; 131 eula[++dfn][0]=x; 132 if(maxs<p[to].wgt) 133 { 134 maxs=p[to].wgt; 135 p[x].mxs=to; 136 } 137 } 138 return ; 139 } 140 void Build_dfs(int x,int top) 141 { 142 if(!x) 143 return ; 144 p[x].ind=++tdn; 145 p[x].tp=top; 146 Build_dfs(p[x].mxs,top); 147 for(int i=p[x].hd;i;i=e[i].lst) 148 { 149 int to=e[i].twd; 150 if(p[to].ind) 151 continue; 152 Build_dfs(to,to); 153 } 154 p[x].oud=tdn; 155 return ; 156 } 157 void Add_dfs(int x,int f) 158 { 159 p[x].Sum=p[x].val; 160 for(int i=p[x].hd;i;i=e[i].lst) 161 { 162 int to=e[i].twd; 163 if(to==f) 164 continue; 165 Add_dfs(to,x); 166 p[x].Sum+=p[to].Sum; 167 } 168 val[p[x].ind]=p[x].Sum; 169 V+=p[x].Sum*(w-p[x].Sum); 170 return ; 171 } 172 int Emin(int x,int y) 173 { 174 return p[x].dp<p[y].dp?x:y; 175 } 176 int Lca(int x,int y) 177 { 178 x=p[x].eind; 179 y=p[y].eind; 180 if(x>y) 181 std::swap(x,y); 182 int l=lg[y-x+1]; 183 return Emin(eula[x][l],eula[y-(1<<l)+1][l]); 184 } 185 int Dis(int x,int y) 186 { 187 int z=Lca(x,y); 188 return p[x].dp+p[y].dp-2*p[z].dp; 189 } 190 void grc_dfs(int x,int f) 191 { 192 p[x].wgt=1; 193 int maxs=-1; 194 for(int i=p[x].hd;i;i=e[i].lst) 195 { 196 int to=e[i].twd; 197 if(to==f||p[to].vis) 198 continue; 199 grc_dfs(to,x); 200 p[x].wgt+=p[to].wgt; 201 if(maxs<p[to].wgt) 202 maxs=p[to].wgt; 203 } 204 maxs=std::max(maxs,size-p[x].wgt); 205 if(maxs<maxsize) 206 { 207 maxsize=maxs; 208 root=x; 209 } 210 return ; 211 } 212 void bin_dfs(int x,int f) 213 { 214 p[x].fa=f; 215 p[x].vis=true; 216 int tmp=size; 217 for(int i=p[x].hd;i;i=e[i].lst) 218 { 219 int to=e[i].twd; 220 if(p[to].vis) 221 continue; 222 root=0; 223 if(p[x].wgt<p[to].wgt) 224 size=tmp-p[x].wgt; 225 else 226 size=p[to].wgt; 227 maxsize=0x3f3f3f3f; 228 grc_dfs(to,to); 229 bin_dfs(root,x); 230 } 231 return ; 232 } 233 void update(int x,lnt y) 234 { 235 p[x].sum+=y; 236 for(int i=x;p[i].fa;i=p[i].fa) 237 { 238 lnt tmp=Dis(x,p[i].fa)*y; 239 p[i].disf+=tmp; 240 p[p[i].fa].diss+=tmp; 241 p[p[i].fa].sum+=y; 242 } 243 return ; 244 } 245 lnt Query(int x) 246 { 247 lnt ans=p[x].diss; 248 for(int i=x;p[i].fa;i=p[i].fa) 249 { 250 lnt tmp=Dis(x,p[i].fa); 251 ans+=p[p[i].fa].diss-p[i].disf; 252 ans+=tmp*(p[p[i].fa].sum-p[i].sum); 253 } 254 return ans; 255 } 256 void Update(int x,lnt v) 257 { 258 while(p[x].tp!=p[1].tp) 259 { 260 update(1,tdn,p[p[x].tp].ind,p[x].ind,1,v); 261 x=p[p[x].tp].ft; 262 } 263 update(1,tdn,p[1].ind,p[x].ind,1,v); 264 return ; 265 } 266 int main() 267 { 268 scanf("%d%d",&n,&m); 269 for(int i=1;i<n;i++) 270 { 271 int a,b; 272 scanf("%d%d",&a,&b); 273 ade(a,b); 274 ade(b,a); 275 } 276 E_dfs(1,1); 277 Build_dfs(1,1); 278 for(int i=2;i<=dfn;i++) 279 lg[i]=lg[i>>1]+1; 280 for(int i=1;i<=20;i++) 281 for(int j=1;j+(1<<i)-1<=dfn;j++) 282 eula[j][i]=Emin(eula[j][i-1],eula[j+(1<<(i-1))][i-1]); 283 root=0; 284 size=n; 285 maxsize=0x3f3f3f3f; 286 grc_dfs(1,1); 287 rt=root; 288 bin_dfs(root,0); 289 for(int i=1;i<=n;i++) 290 { 291 scanf("%lld",&p[i].val); 292 update(i,p[i].val); 293 w+=p[i].val; 294 } 295 Add_dfs(1,1); 296 while(m--) 297 { 298 int cmd; 299 scanf("%d",&cmd); 300 if(cmd==1) 301 { 302 int x,y; 303 scanf("%d%d",&x,&y); 304 lnt dv=y-p[x].val; 305 update(x,dv); 306 V+=dv*Query(x); 307 w+=dv; 308 p[x].val=y; 309 }else{ 310 int x; 311 scanf("%d",&x); 312 lnt ans=-V+w*w; 313 ans+=Query(x)*w; 314 printf("%lld\n",ans); 315 } 316 } 317 return 0; 318 }