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
| const int N=2e5+10,K=19,P=1e9+7;
int n,m,I[N]; struct Edge{ int to,nxt; }e[N<<1]; int head[N],ecnt,deg[N]; void AddEdge(int u,int v){ e[++ecnt]=(Edge){v,head[u]}; head[u]=ecnt,deg[v]++; } #define erep(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
struct BIT{ int n; vector <int> s; BIT(){ }; BIT(int n):n(n){ s.resize(n+1); } void Add(int p,int x){ for(cmin(p,n);p;p-=p&-p) s[p]+=x,Mod1(s[p]); } int Que(int p){ int res=0; while(p<=n) res+=s[p],Mod1(res),p+=p&-p; return res; } } T[N]; vector <BIT> G[N];
int Dep[N],id[K][N],dep[K][N],s[K][N],vis[N],sz[N],fa[N],Root;
int mi,rt; void FindRt(int n,int u,int f){ int ma=0; sz[u]=1; erep(u) if(v!=f && !vis[v]) { FindRt(n,v,u); sz[u]+=sz[v],cmax(ma,sz[v]); } cmax(ma,n-sz[u]); if(mi>ma) mi=ma,rt=u; }
int D,maxd; void dfs(int u,int f,int id){ cmax(maxd,dep[D][u]=dep[D][f]+1),::id[D][u]=id; erep(u) if(v!=f && !vis[v]) { s[D][v]=1ll*s[D][u]*I[deg[u]-1]%P; dfs(v,u,id); } }
int Divide(int n,int u){ mi=1e9,FindRt(n,u,0),u=rt; int sonc=0; vis[u]=s[Dep[u]=D][u]=1,id[D][u]=-1; int t=0; erep(u) if(!vis[v]) { maxd=0; s[D][v]=1,dfs(v,u,sonc); G[u].pb(BIT(maxd)); sonc++; cmax(t,maxd); } T[u]=BIT(t); erep(u) if(!vis[v]) { if(sz[v]>sz[u]) sz[v]=n-sz[u]; D++,fa[Divide(sz[v],v)]=u,D--; } return u; }
int sum[N]; int Que(int u){ ll ans=sum[u]; for(int v=u,d=Dep[v];(d--,v=fa[v]);) ans=(ans+ 1ll* (T[v].Que(dep[d][u])+G[v][id[d][u]].Que(dep[d][u])) *s[d][u])%P; return (ans%P+P)%P; } void Upd(int u,int d){ sum[u]++,Mod1(sum[u]),T[u].Add(d,I[deg[u]]); for(int v=fa[u],D=Dep[u]-1;v;v=fa[v],D--) { if(d<dep[D][u]) continue; int x=1ll*I[deg[u]]*s[D][u]%P; sum[v]+=x,Mod1(sum[v]); x=1ll*x*I[deg[v]-1]%P; T[v].Add(d-dep[D][u],x),G[v][id[D][u]].Add(d-dep[D][u],P-x); } }
int lst; int Get() { return (rd()+lst)%n+1; }
int main(){ I[0]=I[1]=1; rep(i,2,N-1) I[i]=1ll*(P-P/i)*I[P%i]%P; n=rd(),m=rd(); rep(i,2,n){ int u=rd(),v=rd(); AddEdge(u,v),AddEdge(v,u); } Root=Divide(n,1); while(m--) { int opt=rd(); if(opt==1) { int u=Get(),d=Get(); Upd(u,d); } else printf("%d\n",lst=Que(Get())); } }
|