True small fresh ...
In fact, this problem positive solution is dynamic point divide and conquer, but considering the things that need to be vigorously derive a wave and then put on a fantasy strategy game township engage in law, so it was not as strong a wave of derivation, then no brain put a cross + segment tree tree wording ...
First, we consider not change root operations:
When there is no change root operation, provided the amount of change per modification $ \ Delta $, obviously only affect the contribution of each tree on a chain is modified, set $ s_ {i} $ $ I $ is represented by a root node weights and sub-tree, the contribution of each modification to produce the answer is:
$\sum_{i\in [p~root]}(s_{i}+\delta)^{2}-\sum_{i\in [p~root]}s_{i}^{2}$
Expand this expression, too:
$dep_{p}\delta^{2}+2\delta\sum_{i\in [p~root]}s_{i}$
In other words, we actually maintain that $ s_ {i} $, each modification only add to the answer to that expression
While maintaining $ s_ {i} $ + sectional tree may simply modify the segment tree section, inquiry interval calculated
Then consider the next question:
If you change the root of how to do?
We consider the impact after changing the root of the answer:
Obviously from this point it is still on the path to the root node:
We each point on the path set $ p_ {1}, p_ {2}, ... p_ {dep} $ (in order)
Set to a point $ p_ {i} $, when at $ 1 $ is the root of the subtree point right and to $ s_ {i} $, in order to $ p $ root point power and as $ s ^ { '} _ { i} $
Then we consider: for any $ i $, satisfies: $ s_ {i} + s ^ { '} _ {i + 1} = s_ {1} = s ^ {'} _ {dep} $
That is the whole point of the tree and the right node is equal to a half of the right point and the right point and the lower half +
So we now look to derive the answer:
$ 1 $ provided to the root of the answer is $ ans_ {1} $
那么$ans=ans_{1}-\sum_{i=1}^{dep}s_{i}^{2}+\sum_{i=1}^{dep}(s^{'}_{i})^{2}$
With the above expression gives:
$ans=ans_{1}-\sum_{i=1}{dep}s_{i}^{2}+\sum_{i=1}^{dep-1}(s_{1}-s_{i+1})^{2}+(s^{'}_{dep})^{2}$
So that is:
$ans=ans_{1}-\sum_{i=1}^{dep}s_{i}^{2}+deps_{1}^{2}-2s_{1}\sum_{i=2}^{dep}s_{i}+\sum_{i=2}^{dep}s_{i}^{2}$
then:
$ans=ans_{1}+(dep-1)s_{1}^{2}-2s_{1}\sum_{i=1}^{dep}s_{i}+2s_{1}$
Sort out:
$ans=ans_{1}+s_{1}[(dep+1)s_{1}-2\sum_{i=1}^{dep}s_{i}]$
Therefore, we still need to maintain $ s_ {i} $ to
Such tree cross + segment tree can be the perfect solution to this problem
Paste the code:
// luogu-judger-enable-o2 #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #define rt1 rt<<1 #define rt2 (rt<<1)|1 #define ll long long using namespace std; struct Edge { int nxt,to; }edge[400005]; struct Seg_tree { ll lazy,sum; }tree[800005 ]; int head [ 200005 ]; int cnt = 1 ; int siz [ 200005 ], son [ 200005 ], nnum [ 200005 ], ful [ 200005 ], ttop [ 200005 ] dep [ 200005 ] f [ 200005 ]; II w [ 200005 ], s [ 200005 ]; int so many; II ans = 0 ; int n, m; void Add ( int i, int i) { Edge [cut] .nxt =head[l]; edge[cnt].to=r; head[l]=cnt++; } void dfs(int x,int fx) { siz[x]=1,f[x]=fx,dep[x]=dep[fx]+1,s[x]=w[x]; for(int i=head[x];i;i=edge[i].nxt) { int to=edge[i].to; if(to==fx)continue; dfs(to,x); siz[x]+=siz[to],s[x]+=s[to],son[x]=siz[son[x]]<siz[to]?to:son[x]; } ans+=s[x]*s[x]; } void redfs(int x,int topx,int fx) { ttop[x]=topx,nnum[x]=++tot,onum[tot]=x; if(son[x])redfs(son[x],topx,x); for(int i=head[x];i;i=edge[i].nxt) { int to=edge[i].to; if(to==fx||to==son[x])continue; redfs(to,to,x); } } void buildtree(int rt,int l,int r) { if(l==r){tree[rt].sum=s[onum[l]];return;} int mid=(l+r)>>1; buildtree(rt1,l,mid),buildtree(rt2,mid+1,r); tree[rt].sum=tree[rt1].sum+tree[rt2].sum; } void pushdown(int rt,int l,int r) { tree[rt1].lazy+=tree[rt].lazy,tree[rt2].lazy+=tree[rt].lazy; int mid=(l+r)>>1; tree[rt1].sum+=(mid-l+1)*tree[rt].lazy,tree[rt2].sum+=(r-mid)*tree[rt].lazy; tree[rt].lazy=0; } void update(int rt,int l,int r,int lq,int rq,ll v) { if(l>=lq&&r<=rq) { tree[rt].lazy+=v,tree[rt].sum+=(r-l+1)*v; return; } if(tree[rt].lazy)pushdown(rt,l,r); int mid=(l+r)>>1; if(lq<=mid)update(rt1,l,mid,lq,rq,v); if(rq>mid)update(rt2,mid+1,r,lq,rq,v); tree[rt].sum=tree[rt1].sum+tree[rt2].sum; } ll query(int rt,int l,int r,int lq,int rq) { if(l>=lq&&r<=rq)return tree[rt].sum; int mid=(l+r)>>1; if(tree[rt].lazy)pushdown(rt,l,r); ll ret=0; if(lq<=mid)ret+=query(rt1,l,mid,lq,rq); if(rq>mid)ret+=query(rt2,mid+1,r,lq,rq); return ret; } void pushup(int x,ll v) { while(x){update(1,1,n,nnum[ttop[x]],nnum[x],v),x=f[ttop[x]];} } ll l_query(int x) { ll ret=0; while(x){ret+=query(1,1,n,nnum[ttop[x]],nnum[x]),x=f[ttop[x]];} return ret; } template <typename T>inline void read(T &x) { T f=1,c=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();} x=c*f; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<n;i++) { int x,y; read(x),read(y); add(x,y),add(y,x); } for(int i=1;i<=n;i++)read(w[i]); dfs(1,0),redfs(1,1,1); buildtree(1,1,n); while(m--) { int typ; read(typ); if(typ==1) { int x; ll v; read(x),read(v); ans+=(v-w[x])*(v-w[x])*dep[x]; ans+=2*(v-w[x])*l_query(x); pushup(x,v-w[x]); w[x]=v; }else { int x; read(x); ll temp1=query(1,1,n,nnum[1],nnum[1]); ll temp2=l_query(x); ll temps= temp1 * ((dep [x] + 1 ) * temp1- 2 * temp2); printf ( " % lld \ n " , year + time); } } Return 0 ; }