#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;
}
static inline int addmod(int a, int b) {
a += b;
if (a >= mod) a -= mod;
return a;
}
static inline int mulmod(int a, int b) {
if (a*b>=mod){
return a*b%mod;
}else{
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;
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]=mulmod(lazy[id*2],lazy[id]);
lazy[id*2+1]*=mulmod(lazy[id*2+1],lazy[id]);
f[id*2]=mulmod(f[id*2],lazy[id]);
f[id*2+1]=mulmod(f[id*2+1],lazy[id]);
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){
if (l==r){
f[id]=mulmod(f[id],val);
}
lazy[id]=mulmod(lazy[id],val);
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];
for (int i=0;i<=d-cnt;i++){
int pre=t+i;
if (pre>maxdepth){
continue;
}
int len1=length[pre].second-length[pre].first;
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 << mulmod(h[x],pre)<< "\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... |