Submission #721164

#TimeUsernameProblemLanguageResultExecution timeMemory
721164lamSprinkler (JOI22_sprinkler)C++14
38 / 100
2004 ms398828 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...