This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define int long long
using namespace std;
int mod;
struct fen
{
int n;
vector <int> f;
void reset(int sl)
{
f.assign(sl+1,1);
n=sl;
}
void add(int x, int val)
{
// cerr<<n<<endl;
// cerr<<"+ "<<x<<' '<<val<<" : "<<n<<endl;
while (x<=n)
{
f[x]=(f[x]*val)%mod;
x+=(x&-x);
}
}
int get(int x)
{
int temp=1;
while (x>0)
{
temp=(temp*f[x])%mod;
x-=(x&-x);
}
return temp;
}
};
struct fen2
{
int n;
vector <int> f;
void reset(int sl)
{
f.assign(sl+1,1);
n=sl;
}
void add(int x, int val)
{
while (x>0)
{
f[x]=(f[x]*val)%mod;
x-=(x&-x);
}
}
int get(int x)
{
int temp=1;
while (x<=n)
{
temp=(temp*f[x])%mod;
x+=(x&-x);
}
return temp;
}
};
const int maxn = 2e5 + 10;
int n,q;
int a[maxn];
int ppow(int x, int y)
{
int temp=1LL;
while (y)
{
if (y&1) temp=temp*x%mod;
x=x*x%mod;
y/=2;
}
return temp;
}
vector <fen> freq[maxn];
vector <fen2> freq2[maxn];
vector <int> freqs[maxn];
vector <int> adj[maxn],depth[maxn];
int s[maxn],par[maxn],cid[maxn];
bool dau[maxn];
int get_sz(int x, int p)
{
s[x]=1;
for (int i:adj[x])
if (i!=p&&!dau[i]) s[x]+=get_sz(i,x);
return s[x];
}
int find_centroid(int x, int p, int sz)
{
for (int i:adj[x])
if (i!=p&&!dau[i]&&2*s[i]>sz) return find_centroid(i,x,sz);
return x;
}
void dfs(int x, int p, int dep)
{
depth[x].push_back(dep);
for (int i:adj[x])
if (i!=p&&!dau[i]) dfs(i,x,dep+1);
}
void decompose(int x, int p, int id)
{
x=find_centroid(x,x,get_sz(x,x));
par[x]=p;
dau[x]=1;
depth[x].push_back(0);
cid[x]=id;
int cnt=0;
for (int i:adj[x])
if (!dau[i])
{
dfs(i,x,1);
decompose(i,x,cnt);
cnt++;
}
for (int i=0; i<=2; i++)
{
freqs[x].push_back(1LL);
freq[x].emplace_back();
// cerr<<"reset "<<i<<' '<<x<<' '<<cnt<<endl;
freq[x].back().reset(cnt);
// cerr<<freq[x].back().n<<endl;
freq2[x].emplace_back();
freq2[x].back().reset(cnt);
}
}
void update(int x, int D, int w)
{
int p=x; int id=-1;
for (int i=depth[x].size()-1; i>=0; i--)
{
int d = depth[x][i];
if (d<=D)
{
// cout<<"+ "<<D-d<<' '<<p<<' '<<id<<' '<<w<<'\n';
if (id!=-1)
{
freq[p][D-d].add(id+1,w);
freq2[p][D-d].add(id+1,w);
}
else
freqs[p][D-d]=freqs[p][D-d]*w%mod;
}
id=cid[p];
p=par[p];
}
}
int get(int x)
{
int p=x; int id=-1;
int ans = a[x];
for (int i=depth[x].size()-1; i>=0; i--)
{
int D = depth[x][i];
// cout<<p<<" - "<<x<<" = "<<D<<'\n';
for (int d=D; d<=2; d++)
{
ans = (ans*freqs[p][d])%mod;
if (id!=-1)
{
ans = (ans*freq[p][d].get(id))%mod;
ans = (ans*freq2[p][d].get(id+2))%mod;
}
else ans = (ans*freq[p][d].get(freq[p][d].n))%mod;
}
id=cid[p];
p=par[p];
}
return ans;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin>>n>>mod;
for (int i=1; i<n; i++)
{
int u,v; cin>>u>>v;
adj[u].push_back(v);
adj[v].push_back(u);
}
for (int i=1; i<=n; i++) cin>>a[i];
decompose(1,-1,-1);
cin>>q;
for (int i=1; i<=q; i++)
{
int t; cin>>t;
if (t==1)
{
int x,d,w; cin>>x>>d>>w;
// W=w;
update(x,d,w);
}
else
{
int x; cin>>x;
int ans = get(x);
// cout<<x<<" : "<<cnt<<'\n';
cout<<ans<<'\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... |