Test instructions
Given a tree of n nodes, the node number is 1 to n, Root, and sum[p] represents the weights and values of all nodes in this subtrees tree with point P as root.
The calculation supports the following two operations: 1 given a two integer u,v, the weight of the modified point U is v. 2 given two integers l,r, calculate sum[l]+sum[l+1]+....+sum[r-1]+sum[r]
N<=10^5,m<=10^5
Exercises
Each block of statistics sum[i] and, this directly find the DFS sequence maintenance tree array Nlogn statistics on the line.
Then ask for a whole block directly with our statistics of sum[i], and then for the corner rest, we use a tree-like array to the line.
We need to maintain a tree array directly on the x-v[i] when modifying.
Then we have to maintain the block's and, we need to put and add the number of ancestors of the block I (including i) * (X-v[i]).
So we preprocess the f[i][j] representing the number of ancestors of J (including J) in Block I. This DFS uses an array to record the ancestor situation (add itself when entering, minus itself when it is rolled out), and for each point sweep over each block statistic.
And then this question to use unsigned long long then also can't open, will Mle
1#include <iostream>2#include <cstring>3#include <cstdio>4#include <cmath>5#include <algorithm>6 using namespacestd;7 Const intn=100100;8 intCnt,head[n];9 intSize[n],id[n],tot;Ten intnum[ -],block[n],f[ -][n]; OneUnsignedLong Longsum[ -],a[n],tr[n],ans,v[n]; A intn,m,r[ -],l[ -],block,root; - structedge{ - intto,nxt; the}e[n*2]; - voidAddintUintv) { -cnt++; -e[cnt].nxt=Head[u]; +e[cnt].to=v; -head[u]=CNT; + } A voidDFS1 (intUintFA) { atsize[u]=1; -id[u]=++tot; - for(intI=head[u];i;i=e[i].nxt) { - intv=e[i].to; - if(V==FA)Continue; - DFS1 (v,u); insize[u]+=Size[v]; - } to } + voidDFS2 (intUintFA) { -num[block[u]]++; the for(intI=1; i<=block[n];i++){ *f[i][u]+=Num[i]; $ }Panax Notoginseng for(intI=head[u];i;i=e[i].nxt) { - intv=e[i].to; the if(V==FA)Continue; + DFS2 (v,u); A } thenum[block[u]]--; + } - intLowbit (intx) { $ returnx&-x; $ } - voidUpdateintx,unsignedLong LongW) { - for(inti=x;i<=n;i+=lowbit (i)) { thetr[i]+=W; - }Wuyi } theUnsignedLong LongQueryintx) { -UnsignedLong Longtmp=0; Wu for(inti=x;i;i-=lowbit (i)) { -tmp+=Tr[i]; About } $ returntmp; - } - intMain () { -scanf"%d%d",&n,&m); A for(intI=1; i<=n;i++){ +scanf"%llu",&v[i]); the } - for(intI=1; i<=n;i++){ $ intu,v; thescanf"%d%d",&u,&v); the if(u==0){ theroot=v; the Continue; - } in Add (u,v); the Add (v,u); the } AboutDFS1 (Root,0); the for(intI=1; i<=n;i++){ the Update (id[i],v[i]); the } + for(intI=1; i<=n;i++){ -A[i]=query (id[i]+size[i]-1)-query (id[i]-1); the //cout<<i<< "<<id[i]<<" "<<size[i]<<" "<<a[i]<<endl;Bayi } theblock=sqrt (n); the for(intI=1; i<=n;i++){ -block[i]= (I-1)/block+1; -sum[block[i]]+=A[i]; the if(! L[block[i]]) l[block[i]]=i; ther[block[i]]=i; the } theDFS2 (Root,0); - while(m--){ the intk,x,y; thescanf"%d%d%d",&k,&x,&y); the if(k==1){94 for(intI=1; i<=block[n];i++){ thesum[i]+=f[i][x]* (yv[x]); the } theUpdate (id[x],y-v[x]);98v[x]=y; About } - Else{101ans=0;102 if(block[x]+1>=Block[y]) {103 for(inti=x;i<=y;i++){104Ans+=query (id[i]+size[i]-1)-query (id[i]-1); the }106 }107 Else{108 for(inti=block[x]+1; i<=block[y]-1; i++){109ans+=Sum[i]; the }111 for(inti=x;i<=r[block[x]];i++){ theAns+=query (id[i]+size[i]-1)-query (id[i]-1);113 } the for(inti=l[block[y]];i<=y;i++){ theAns+=query (id[i]+size[i]-1)-query (id[i]-1); the }117 }118printf"%llu\n", ans);119 } - }121 return 0;122}
[bzoj4765] General calculation ji (block + Tree array +dfs order)