● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
直接搞
typedef long long LL ; const int maxn = 100208 ; LL c1[maxn] , c2[maxn] , ans1[maxn] , ans2[maxn] ; int n ; int siz[maxn] , top[maxn] , son[maxn] ; int dep[maxn] , tid[maxn] , fa[maxn] , rank[maxn] ; int head[maxn] , to[maxn*2] , next[maxn*2] , edge ; int tim ; void init(){ memset(head , -1 , sizeof(head)) ; memset(son , -1 , sizeof(son)) ; memset(c1 , 0 , sizeof(c1)) ; memset(c2 , 0 , sizeof(c2)) ; tim = edge = 0 ; } void addedge(int u , int v){ to[edge] = v , next[edge] = head[u] , head[u] = edge++ ; to[edge] = u , next[edge] = head[v] , head[v] = edge++ ; } void dfs1(int u , int father , int d){ dep[u] = d ; fa[u] = father ; siz[u] = 1 ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != father){ dfs1(v , u , d+1) ; siz[u] += siz[v] ; if(son[u] == -1 || siz[v] > siz[son[u]]) son[u] = v ; } } } void dfs2(int u , int tp){ top[u] = tp ; tid[u] = ++tim ; rank[tid[u]] = u ; if(son[u] == -1) return ; dfs2(son[u] , tp) ; for(int i = head[u] ; i != -1 ; i = next[i]){ int v = to[i] ; if(v != son[u] && v != fa[u]) dfs2(v , v) ; } } void in1(int l , int r , int c){ c1[l] += c ; c1[r+1] -= c ; } void gsum1(){ LL t = 0 ; for(int i = 1 ; i <= n ; i++){ t += c1[i] ; ans1[i] = t ; } } void in2(int l , int r , int c){ c2[l] += c ; c2[r+1] -= c ; } void gsum2(){ LL t = 0 ; for(int i = 1 ; i <= n ; i++){ t += c2[i] ; ans2[i] = t ; } } struct Line{ int u , v ; }li[maxn] ; void change2(int x , int y , int d){ while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) std::swap(x , y) ; in2(tid[top[x]] , tid[x] , d) ; x = fa[top[x]] ; } if(x == y) return ; if(dep[x] > dep[y]) std::swap(x , y) ; in2(tid[x]+1 , tid[y] , d) ; } void change1(int x , int y , int d){ while(top[x] != top[y]){ if(dep[top[x]] < dep[top[y]]) std::swap(x , y) ; in1(tid[top[x]] , tid[x] , d) ; x = fa[top[x]] ; } if(dep[x] > dep[y]) std::swap(x , y) ; in1(tid[x] , tid[y] , d) ; } int main(){ int i , j , u , v , k , t , T = 1 , m , d ; char s[8] ; cin>>t ; while(t--){ scanf("%d%d" , &n , &m) ; init() ; for(i = 1 ; i < n ; i++){ scanf("%d%d",&li[i].u , &li[i].v) ; addedge(li[i].u , li[i].v) ; } dfs1(1 , 0 , 0) ; dfs2(1 , 1) ; for(i = 1 ; i < n ; i++){ if(tid[li[i].u] < tid[li[i].v]) std::swap(li[i].u , li[i].v) ; } for(i = 1 ; i <= m ; i++){ scanf("%s%d%d%d" , s , &u , &v , &d) ; if(s[3] == '2') change2(u , v , d) ; else change1(u , v , d) ; } gsum1() ; gsum2() ; printf("Case #%d:\n" , T++) ; printf("%I64d" , ans1[tid[1]]) ; for(i = 2 ; i <= n ; i++) printf(" %I64d" , ans1[tid[i]]) ; puts("") ; if(n == 1) puts("") ; else{ printf("%I64d" , ans2[tid[li[1].u]]) ; for(i = 2 ; i < n ; i++) printf(" %I64d" , ans2[tid[li[i].u]]) ; puts("") ; } } return 0 ; }