#include <bits/stdc++.h>
#define int long long
using namespace std;
int a,mod;
vector <int> z[1000005];
int h[1000005];
int sta[1000005];
int fin[1000005];
int tour;
vector <int> depth[1000005];
int par[1000005];
int high[1000005];
int base[1000005];
int maxdepth=0;
int cur=1;
bool cmp(int a,int b){
return a<b;
}
int sbd(int i){
int res=base[high[i]];
int t=high[i];
int pre=lower_bound(depth[t].begin(),depth[t].end(),sta[i])-depth[t].begin()+1;
if (pre+base[t]>a || pre+base[t]>a){
cout << i << " " << t << " " << depth[t].size() << "\n";
}
res+=pre;
return res;
}
void dfs(int i,int j,int k){
par[i]=j;
tour++;
sta[i]=tour;
maxdepth=max(maxdepth,k);
depth[k].push_back(sta[i]);
for (auto p:z[i]){
if (p==j){
continue;
}
high[p]=high[i]+1;
dfs(p,i,k+1);
}
fin[i]=tour;
}
int f[4000005];
int lazy[4000005];
pair<int,int> length[1000005];
void push(int id){
if (lazy[id]!=1){
lazy[id*2]*=lazy[id];
lazy[id*2+1]*=lazy[id];
lazy[id*2]%=mod;
lazy[id*2+1]%=mod;
f[id*2]*=lazy[id];
f[id*2+1]*=lazy[id];
f[id*2]%=mod;
f[id*2+1]%=mod;
lazy[id]=1;
}
}
void update(int id,int l,int r,int x,int y,int val){
if (x>r || y<l){
return;
}
if (l>=x && y>=r){
f[id]*=val;
f[id]%=mod;
lazy[id]=(lazy[id]*val)%mod;
return;
}
int mid=(l+r)/2;
push(id);
update(id*2,l,mid,x,y,val);
update(id*2+1,mid+1,r,x,y,val);
f[id]=f[id*2]+f[id*2+1];
}
int get(int id,int l,int r,int pos){
if (l==r){
return f[id];
}
int mid=(l+r)/2;
push(id);
if (pos<=mid){
return get(id*2,l,mid,pos);
}else{
return get(id*2+1,mid+1,r,pos);
}
}
bool vis[1000005];
void query(int n,int w){
for (int i=1;i<=min(n,maxdepth);i++){
vis[i]=true;
int sta1=base[i]+1;
int fin1=base[i]+depth[i].size();
update(1,1,a,sta1,fin1,w);
}
}
void querydown(int n,int d,int w){
int cnt=0;
int sta1=high[n];
while (sta1<=maxdepth && cnt<=d){
if (!vis[sta1]){
int pos1=lower_bound(depth[sta1].begin(),depth[sta1].end(),sta[n])-depth[sta1].begin()+1+base[sta1];
int pos2=upper_bound(depth[sta1].begin(),depth[sta1].end(),fin[n])-depth[sta1].begin()+base[sta1];
// if (pos1>a || pos2>a){
// cout << "ok" << "\n";
// return;
// }
if (pos1<=pos2){
update(1,1,a,pos1,pos2,w);
vis[sta1]=true;
}
// if (cur==1){
// cout << sta1<< " " << pos1 << " " << pos2 << "\n";
// }
}
sta1++;
cnt++;
}
}
void queryup(int n,int d,int w){
int cnt=0;
while (cnt<=d && n!=0){
int t=high[n];
// if (cur==1){
// cout << n << "\n";
// }
for (int i=0;i<=d-cnt;i++){
int pre=t+i;
if (pre>maxdepth){
continue;
}
int len1=length[pre].second-length[pre].first;
// if ( cur==1&& pre==4){
// cout << "ok" << " " <<fin[n]-sta[n] << "\n";
// }
int len2=fin[n]-sta[n];
if (len1<len2){
length[pre]={sta[n],fin[n]};
}
}
cnt++;
n=par[n];
}
}
void bruh(int id,int l,int r){
if (l==r){
cout << f[id] << " ";
return;
}
int mid=(l+r)/2;
push(id);
bruh(id*2,l,mid);
bruh(id*2+1,mid+1,r);
}
void query1(int x,int d,int w){
int t=high[x];
for (int i=0;i<=d;i++){
if (t-i<=0){
break;
}
int sta1=t-i;
int pos1=lower_bound(depth[sta1].begin(),depth[sta1].end(),length[t-i].first)-depth[sta1].begin()+1+base[sta1];
int pos2=upper_bound(depth[sta1].begin(),depth[sta1].end(),length[t-i].second)-depth[sta1].begin()+base[sta1];
if (pos1<=pos2){
update(1,1,a,pos1,pos2,w);
}
}
for (int i=1;i<=d;i++){
if (t+i>maxdepth){
break;
}
int sta1=t+i;
int pos1=lower_bound(depth[sta1].begin(),depth[sta1].end(),length[sta1].first)-depth[sta1].begin()+1+base[sta1];
int pos2=upper_bound(depth[sta1].begin(),depth[sta1].end(),length[sta1].second)-depth[sta1].begin()+base[sta1];
if (pos1<=pos2){
update(1,1,a,pos1,pos2,w);
}
}
}
signed main()
{
// freopen("test.txt", "r", stdin);
// freopen("o2.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> a >> mod;
for (int i=1;i<a;i++){
int x,y;
cin >> x >> y;
z[x].push_back(y);
z[y].push_back(x);
}
for (int i=1;i<=a;i++){
cin >> h[i];
}
dfs(1,0,1);
for (int i=1;i<=maxdepth;i++){
base[i]=base[i-1]+depth[i-1].size();
sort(depth[i].begin(),depth[i].end(),cmp);
vis[i]=false;
}
for (int i=1;i<=a;i++){
high[i]++;
}
for (int i=1;i<=4*a+5;i++){
lazy[i]=1;
f[i]=1;
}
// for (int i=1;i<=maxdepth;i++){
// cout << base[i] << "\n";
// }
// cout << sta[3] << " " << sta[5] << "\n";
int q;
cin >> q;
// cout << sta[5] << " " << fin[5] << "\n";
// cout << "\n";
while (q--){
int c;
cin >> c;
if (c==2){
int x;
cin >> x;
int pos=sbd(x);
int pre=get(1,1,a,pos);
// cout << "query" << "\n";
//cout << pos << " ";
cout << (h[x]*pre)%mod << "\n";
// cout << "\n";
}else{
int x,d,w;
cin >> x >> d >> w;
int t=high[x];
for (int i=0;i<=d;i++){
length[max(t-i,1LL)]={0,-1};
length[t+i]={0,-1};
}
// dfs1(x,x,0,w);
queryup(x,d,w);
// if (cur==1){
// for (int i=1;i<=maxdepth;i++){
// cout << length[i].first << " " << length[i].second << "\n";
// }
// }
query1(x,d,w);
t=high[x];
for (int i=0;i<=d;i++){
length[max(t-i,1LL)]={0,-1};
length[t+i]={0,-1};
}
}
// cout << cur << "\n";
// bruh(1,1,a);
// cout << "\n";
// for (int i=1;i<=a;i++){
// cout << h[i] << " ";
// }
// cur++;
// cout << "\n";
// cout << "\n";
}
// for (int i=1;i<=maxdepth;i++){
// cout << "depth " << i << "\n";
// for (auto p:depth[i]){
// cout << p << "\n";
// }
// cout << "\n";
// }
return 0;
}
/*
9 11
2 1
3 2
4 1
5 1
6 1
7 5
8 6
9 4
2
1
3
5
4
4
4
5
4
4
2 5
1 8 3 6
1 5 4 3
2 6
9 20
2 1
3 1
4 1
5 1
6 1
7 6
8 6
9 7
4
2
2
2
5
2
3
3
3
5
1 7 3 3
2 3
1 6 7 6
1 2 5 2
1 6 7 0
9 7
2 1
3 1
4 2
5 3
6 1
7 3
8 6
9 6
2
1
5
3
3
1
1
3
1
3
1 7 3 6
2 7
2 5
*/
/*
5
10 9 3 6 1
3
2 1 2 4
1 2 4
1 2 2
5
2 8 6 4 1
4
3 1 2 9
1 1 3
2 1 4 5
1 2 5
*/
/*
8
01010101
10111000
8
01010101
10111000
10101010
6
110110
011101
001001
8
01010101
11000010
10101010
*/
/*
freopen("test.txt", "r", stdin);
freopen("o2.out", "w", stdout);
*/
# | 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... |