树链剖分
区间点更新 区间边更新 最后输出所有的点和边
用线段树维护会超时 所以采用差分数组来维护(题意已经暗示的很明显了 直到最后再查询 )
因为一个小细节wa 了 2 小时!!!!!!!!
注意初始化 siz[0]=0; dep[root]=0; 其他的树链剖分全部不用初始化
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 // #define inf 0x3f3f3f3f3f3f3f3f const int N=100005; int pos,head[N],id[N],top[N],fa[N],son[N],cnt,siz[N],dep[N],n,m,a,b,s[N][3]; ll d[N],d2[N]; int c; char ss[7]; struct Edge { int to,nex; }edge[N<<1]; void add(int a,int b) { edge[++pos]=Edge{b,head[a]}; head[a]=pos; } void dfs1(int x,int f) { dep[x]=dep[f]+1; fa[x]=f; siz[x]=1; son[x]=0; for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; if(v==f)continue; dfs1(v,x); siz[x]+=siz[v]; if(siz[v]>siz[son[x]])son[x]=v; } } void dfs2(int x,int topf) { id[x]=++cnt; top[x]=topf; if(son[x]) dfs2(son[x],topf); for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; if(v==son[x]||v==fa[x])continue; dfs2(v,v); } } void UP(int x,int y,int v) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])swap(x,y); d[id[top[x]]]+=v; d[id[x]+1]-=v; x=fa[top[x]]; } if(id[x]>id[y])swap(x,y); d[id[x]]+=v; d[id[y]+1]-=v; } void UP2(int x,int y,int v) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])swap(x,y); d2[id[top[x]]]+=v; d2[id[x]+1]-=v; x=fa[top[x]]; } if(id[x]>id[y])swap(x,y); d2[id[x]+1]+=v; d2[id[y]+1]-=v; } void init() { cnt=pos=0; CLR(head,0);CLR(d,0);CLR(d2,0);dep[1]=0;siz[0]=0; } int main() { int cas;RI(cas); rep(kase,1,cas) { init(); RII(n,m); rep(i,1,n-1) { RII(a,b);add(a,b);add(b,a);s[i][1]=a;s[i][2]=b; } dfs1(1,1);dfs2(1,1); rep(i,1,m) { RS(ss);RII(a,b);RI(c); if(ss[3]=='1')UP(a,b,c); else if(ss[3]=='2') UP2(a,b,c); } rep(i,1,n) { d[i]+=d[i-1]; d2[i]+=d2[i-1]; } printf("Case #%d:\n",kase); rep(i,1,n) { if(i!=1)printf(" "); printf("%lld",d[id[i]] ); } printf("\n"); rep(i,1,n-1) { if(i!=1)printf(" "); if(dep[s[i][1]]<dep[s[i][2]]) printf("%lld",d2[id[s[i][2]]]); else printf("%lld",d2[id[s[i][1]]]); } printf("\n"); } return 0; }