#include <bits/stdc++.h>
#define int long long
using namespace std;
int a,mod;
vector <int> z[250001];
int h[250001];
int sta[250001];
int fin[250001];
int tour;
vector <int> depth[250001];
int par[250001];
int high[250001];
int base[250001];
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[250005*4];
int lazy[250005*4];
pair<int,int> length[250001];
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);
}
}
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 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()
{
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);
}
for (int i=1;i<=a;i++){
high[i]++;
}
for (int i=1;i<=4*a+5;i++){
lazy[i]=1;
f[i]=1;
}
int q;
cin >> q;
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 << (h[x]*pre)%mod << "\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};
}
queryup(x,d,w);
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};
}
}
}
return 0;
}
# | 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... |