#include<bits/stdc++.h>
using namespace std;
#define pb push_back
int mod;
int mul(long long i,int j){
  return i*j%mod;
}
struct fenw{
  int*tree[42];
  int n,m;
  void init(int M){
    n=41,m=M;
    for(int i=1;i<=n;i++){
      tree[i]=new int[n+1];
      for(int j=1;j<=m;j++)tree[i][j]=1;
    }
  }
  void update(int x,int y,int val){
    x++;
    for(int i=x;i<=n;i+=i&-i){
      for(int j=y;j<=m;j+=j&-j){
        tree[i][j]=mul(tree[i][j],val);
      }
    }
  }
  int query(int x,int y){
    x++;
    int ans=1;
    for(int i=x;i;i-=i&-i){
      for(int j=y;j;j-=j&-j){
        ans=mul(tree[i][j],ans);
      }
    }
    return ans;
  }
};
const int lim=2e5+100;
vector<int>v[lim];
int tot;
bool vis[lim];
int sz[lim];
int dis[18][lim];
int col[18][lim];
int parent[lim];
int layer[lim];
fenw fw[lim][2];
int sbs(int node,int par,int dep){
  dis[dep][node]=par?(dis[dep][par]+1):0;
  sz[node]=1;
  for(int j:v[node]){
    if(vis[j]||j==par)continue;
    sz[node]+=sbs(j,node,dep);
  }
  return sz[node];
}
int findcen(int node,int par){
  for(int j:v[node]){
    if(vis[j]||j==par)continue;
    if(tot<2*sz[j])return findcen(j,node);
  }
  return node;
}
void color(int node,int par,int dep,int code){
  col[dep][node]=code;
  for(int j:v[node]){
    if(vis[j]||j==par)continue;
    color(j,node,dep,code);
  }
}
void decomp(int node,int par,int dep=0){
  tot=sbs(node,0,dep);
  int cent=findcen(node,0);
  sbs(cent,0,dep);
  vis[cent]=1;
  layer[cent]=dep;
  parent[cent]=par;
  int code=0;
  for(int j:v[cent]){
    if(vis[j])continue;
    color(j,cent,dep,++code);
  }
  fw[cent][0].init(code);
  fw[cent][1].init(code);
  for(int j:v[cent]){
    if(vis[j])continue;
    decomp(j,cent,dep+1);
  }
}
int h[lim];
int applied[lim][41];
void update(int node,int ds,int val){
  h[node]=mul(h[node],val);
  for(int i=0;i<=ds;i++){
    applied[node][i]=mul(applied[node][i],val);
  }
  int curdep=layer[node],curnode=node;
  while(1){
    if(node==curnode){
    }else if(0<=40-ds+dis[curdep][node]&&40-ds+dis[curdep][node]<=40){
      fw[curnode][0].update(40-ds+dis[curdep][node],col[curdep][node],val);
      fw[curnode][1].update(40-ds+dis[curdep][node],fw[curnode][1].m-col[curdep][node]+1,val);
    }
    if(!layer[curnode])break;
    curdep--;
    curnode=parent[curnode];
  }
}
int query(int node){
  int ans=h[node];
  int curdep=layer[node],curnode=node;
  while(1){
    if(node==curnode){
      ans=mul(ans,fw[curnode][0].query(40,fw[curnode][0].m));
    }else if(dis[curdep][node]<=40){
      ans=mul(ans,applied[curnode][dis[curdep][node]]);
      ans=mul(ans,fw[curnode][0].query(40-dis[curdep][node],col[curdep][node]-1));
      ans=mul(ans,fw[curnode][1].query(40-dis[curdep][node],fw[curnode][1].m-col[curdep][node]));
    }
    if(!layer[curnode]||!ans)break;
    curdep--;
    curnode=parent[curnode];
  }
  return ans;
}
int main(){
  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  int n;
  cin>>n>>mod;
  for(int i=0;i<n-1;i++){
    int x,y;
    cin>>x>>y;
    v[x].pb(y);
    v[y].pb(x);
  }
  for(int i=1;i<=n;i++){
    cin>>h[i];
    for(int j=0;j<=40;j++){
      applied[i][j]=1;
    }
  }
  decomp(1,0);
  int q;
  cin>>q;
  while(q--){
    int ty;
    cin>>ty;
    if(ty==1){
      int x,d,w;
      cin>>x>>d>>w;
      update(x,d,w);
    }else{
      int node;
      cin>>node;
      cout<<query(node)<<'\n';
    }
  }
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |