1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include<bits/stdc++.h> #define re register typedef long long ll; template<class T> inline void read(T &x) { x=0; char ch=getchar(),t=0; while(ch<'0'||ch>'9') t|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); if(t) x=-x; } template<class T,class ...T1> inline void read(T &x,T1 &...x1){ read(x),read(x1...); } template<class T> inline void write(T x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } template<> inline void write(bool x){ putchar(x?'1':'0'); } template<> inline void write(char c){ putchar(c); } template<> inline void write(char *s){ while(*s!='\0') putchar(*s++); } template<> inline void write(const char *s){ while(*s!='\0') putchar(*s++); } template<class T,class ...T1> inline void write(T x,T1 ...x1){ write(x),write(x1...); } template<class T> inline bool checkMax(T &x,T y){ return x<y?x=y,1:0; } template<class T> inline bool checkMin(T &x,T y){ return x>y?x=y,1:0; } const int MAXN=1e5+10,MAXS=50; const int S=29; int N,Q; struct G { int next,to; }Edge[MAXN<<1]; int Head[MAXN],Total; inline void addEdge(int u,int v) { Edge[++Total]=(G){Head[u],v};Head[u]=Total; Edge[++Total]=(G){Head[v],u};Head[v]=Total; } int Fa[MAXN],Siz[MAXN],Dfn[MAXN],Num[MAXN][MAXS],Cnt; void dfsTree(int x,int last) { Fa[x]=last,Siz[x]=1,Dfn[x]=++Cnt; Num[x][0]=1; for(int e=Head[x],v;e;e=Edge[e].next) { if((v=Edge[e].to)==last) continue; dfsTree(v,x); Siz[x]+=Siz[v]; for(int s=1;s<=S;++s) Num[x][s]+=Num[v][s-1]; } } ll ans,Asum,Acnt,Val[MAXN][MAXS]; struct BIT { ll Tre[MAXN],Siz; inline void build(int n){ Siz=n;for(int i=0;i<=n;++i) Tre[i]=0; } inline int lowbit(int x){ return x&(-x); } inline void add(int x,ll v){ for(;x<=Siz;x+=lowbit(x)) Tre[x]+=v; } inline ll query(int x) { ll res=0; for(;x;x-=lowbit(x)) res+=Tre[x]; return res; } inline ll get(int l,int r){ return query(r)-query(l-1); } }Tre; inline void modify(int x,int y,ll p) { ll tot=0; for(int i=0;y;++i,y/=p) Val[x][i]+=y,tot+=(ll)Num[x][i]*y; Tre.add(Dfn[x],tot),Asum+=tot; } int main() { read(N,Q);Tre.build(N); for(int i=2,u,v;i<=N;++i) read(u,v),addEdge(u,v); dfsTree(N,0); for(int opt,u,v;Q--;) { read(opt,u,v); if(opt==1) { ll p;read(p); if(p==1) Asum+=(ll)N*v,Acnt+=v; else { modify(u,v,p),v/=p; for(int i=Fa[u],lst=u;i&&v>0;i=Fa[i],lst=Fa[lst],v/=p) modify(i,v,p),modify(lst,-(v/p),p); } } else { bool rev=0; if(Fa[v]==u) std::swap(u,v),rev=1; ans=Tre.get(Dfn[u],Dfn[u]+Siz[u]-1)+Acnt*Siz[u]; for(int s=1;s<=S&&v;++s,v=Fa[v]) for(int t=0;s+t<=S;++t) ans+=(ll)Val[v][s+t]*Num[u][t]; if(rev) write(Asum-ans,' ',ans,'\n'); else write(ans,' ',Asum-ans,'\n'); } } return 0; }
|