1 条题解
-
0
#include<bits/stdc++.h> using namespace std; #define eb emplace_back #define LL long long template<typename T> void qr(T& x) { char c=getchar(); x=0; int f=1; for(; !isdigit(c); c=getchar()) if(c=='-') f=-1; for(; isdigit(c); c=getchar()) x=x*10+(c-'0'); x*=f; } template<typename T> void qw(T x) { if(x<0) putchar('-'), x=-x; if(x/10) qw(x/10); putchar(x%10+'0'); } const int N=1e6+10; vector<int> G[N]; int n;LL v[N]; int fa[N], siz[N], dep[N], son[N]; void dfs1(int x, int xfa) { fa[x]=xfa; dep[x]=dep[xfa]+1; siz[x]=1; son[x]=0; for(int y: G[x]) if(y!=xfa) { dfs1(y, x); siz[x]+=siz[y]; if(siz[y]>siz[son[x]]) son[x]=y; } } int tsp, dfn[N], top[N]; void dfs2(int x, int tp) { dfn[x]=++tsp; top[x]=tp; if(son[x]) dfs2(son[x], tp); for(int y: G[x]) if(y!=son[x] && y!=fa[x]) dfs2(y, y); } int LCA(int x,int y) { for(;top[x]!=top[y];x=fa[top[x]])if(dep[top[x]]<dep[top[y]])swap(x, y); return dep[x]<dep[y] ? x : y; } LL c1[N], c2[N]; void add(LL c[], int x, LL k){if(x==0) return ;for(; x<=n; x+=x&-x) c[x]+=k;} LL sum(LL c[], int x){LL res=0;for(; x>=1; x-=x&-x) res+=c[x];return res;} LL getsum(LL c[], int l, int r){return sum(c, r)-sum(c, l-1);} int main() { int m,rt; qr(n),qr(m),qr(rt); for(int i=1; i<=n; i++)qr(v[i]); for(int i=1, x, y; i<n; i++) qr(x),qr(y),G[x].eb(y), G[y].eb(x); dep[0]=0; dfs1(rt, 0); tsp=0; dfs2(rt, rt); for(int i=1; i<=n; i++) { add(c1, dfn[i], v[i]); add(c2, dfn[i], v[i]*dep[i] ); add(c1, dfn[fa[i]], -v[i]); add(c2, dfn[fa[i]], -v[i]*dep[fa[i]]); } while(m--) { int op; scanf("%d", &op); if(op==1) //1 x y k,表示将「结点 x 到结点 y 的简单路径」上所有结点的权值都增加 k { int x, y; LL k; qr(x); qr(y); qr(k); int lca=LCA(x, y), flca=fa[lca]; add(c1, dfn[x], k); add(c2, dfn[x], k*dep[x] ); add(c1, dfn[y], k); add(c2, dfn[y], k*dep[y] ); add(c1, dfn[lca],-k); add(c2, dfn[lca], -k*dep[lca] ); add(c1,dfn[flca],-k); add(c2,dfn[flca], -k*dep[flca]); } else if(op==2) //2 x,表示求结点 x 的权值 { int x; qr(x); int l=dfn[x], r=dfn[x]+siz[x]-1; qw( getsum(c1, l, r) ); printf("\n"); } else //3 x,表示求 x 的子树上所有结点的权值之和 { int x; qr(x); int l=dfn[x], r=dfn[x]+siz[x]-1; qw( getsum(c2, l, r)-getsum(c1, l, r)*(dep[x]-1) ); printf("\n"); } } return 0; }
- 1
信息
- ID
- 649
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 213
- 已通过
- 34
- 上传者