● 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 ;
}