#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 2e5 + 5;
int n, q, mod;
int a[maxn];
vector<int> adj[maxn];
array<int, 4> qr[maxn];
struct sub1{
    int d[1005][1005];
    void dfsd(int x, int p, int *d)
    {
        d[x] = d[p] + 1;
        for (int i : adj[x]) if (i != p)
            dfsd(i, x, d);
    }
    sub1()
    {
        for (int i = 1; i <= n; i++)
        {
            d[i][i] = -1;
            dfsd(i, i, d[i]);
        }
        for (int j = 1; j <= q; j++)
        {
            int t = qr[j][0], x = qr[j][1], D = qr[j][2], val = qr[j][3];
            if (t == 1)
            {
                for (int i = 1; i <= n; i++)
                    if (d[i][x] <= D)
                        a[i] = (a[i] * val) % mod;
            }
            else cout << a[x] << "\n";
        }
    }
};
struct sub23{
    int in[maxn], out[maxn], h[maxn], par[maxn];
    struct node{
        node *l, *r;
        int p;
        node(int v = 1)
        {
            l = r = 0;
            p = v;
        }
    };
    node *root[maxn];
    inline void mul(int &x, int y)
    {
        x *= y;
        x %= mod;
    }
    void upd(int lx, int rx, int val, node *id, int l = 1, int r = n)
    {
        if (lx > rx || l > rx || lx > r) return;
        if (lx <= l && r <= rx) return mul(id -> p, val);
        int mid = (l + r) / 2;
        if (!id -> l) id -> l = new node();
        if (!id -> r) id -> r = new node();
        upd(lx, rx, val, id -> l, l, mid);
        upd(lx, rx, val, id -> r, mid + 1, r);
    }
    int qry(int pos, node *id, int l = 1, int r = n)
    {
        if (!id) return 1;
        if (l == r) return id -> p;
        int mid = (l + r) / 2;
        if (pos <= mid) return (id -> p * qry(pos, id -> l, l, mid)) % mod;
        return (id -> p * qry(pos, id -> r, mid + 1, r)) % mod;
    }
    int max_depth = 0, cnt = 0;
    void dfs(int x = 1, int p = 0)
    {
        in[x] = ++cnt;
        h[x] = h[p] + 1;
        par[x] = p;
        max_depth = max(max_depth, h[x]);
        for (int i : adj[x]) if (i != p)
            dfs(i, x);
        out[x] = cnt;
    }
    inline void apply(int l, int r, int u, int v, int f, int d, int val)
    {
        for (int i = 1; i <= d; i++)
        {
            if (f + i > max_depth) return;
            if (!root[f + i]) root[f + i] = new node();
            if (u == -1) upd(l, r, val, root[f + i]);
            else upd(l, u - 1, val, root[f + i]), upd(v + 1, r, val, root[f + i]);
        }
    }
    void update(int x, int D, int val)
    {
        int d = 0;
        apply(in[x], out[x], -1, -1, h[x], D, val);
        mul(a[x], val);
        int pre = x;
        x = par[x];
        while (D--)
        {
            if (!x) return;
            apply(in[x], out[x], in[pre], out[pre], h[x], D, val);
            pre = x;
            mul(a[x], val);
            x = par[x];
        }
    }
    int solve(int x)
    {
        int ans = a[x];
        mul(ans, qry(in[x], root[h[x]]));
        return ans;
    }
    sub23()
    {
        dfs();
        for (int j = 1; j <= q; j++)
        {
            int t = qr[j][0], x = qr[j][1], D = qr[j][2], val = qr[j][3];
            if (t == 1) update(x, D, val);
            else
                cout << solve(x) << "\n";
        }
    }
};
struct sub45{
    int mark[maxn], sz[maxn], par[maxn], mu[maxn];
    vector<int> anc[maxn];
    struct DS{
        int n;
        vector<int> f;
        void reset(int _n)
        {
            n = _n;
            f.resize(n + 1, 0);
        }
        void upd(int l, int r, int val)
        {
            l = max(0ll, l - 1);
            r = min(r, n);
            if (l > r) return;
            for (; l > 0; l -= l & -l)
                f[l] -= val;
            for (; r > 0; r -= r & -r)
                f[r] += val;
        }
        int get(int x)
        {
            if (x == 0) return 0;
            int ans = 0;
            for (; x <= n; x += x & -x)
                ans += f[x];
            return ans;
        }
    } A[maxn], B[maxn];
    void get_size(int x, int p)
    {
        sz[x] = 1;
        for (int i : adj[x]) if (i != p && !mark[i])
            get_size(i, x),
            sz[x] += sz[i];
    }
    int find(int x, int p, int half)
    {
        for (int i : adj[x])
            if (i != p && !mark[i] && sz[i] > half)
                return find(i, x, half);
        return x;
    }
    void dfs(int x, int p, int c, int d)
    {
        anc[x].emplace_back(d);
        for (int i : adj[x]) if (i != p && !mark[i])
            dfs(i, x, c, d + 1);
    }
    void solve(int x, int pre)
    {
        get_size(x, x);
        int size = sz[x];
        x = find(x, x, sz[x] / 2);
        mark[x] = 1;
        par[x] = pre;
        A[x].reset(size + 5);
        B[x].reset(size + 5);
        dfs(x, x, x, 0);
        for (int i : adj[x]) if (!mark[i])
            solve(i, x);
    }
    void upd(int x, int l, int r, int val)
    {
        int u = x;
        for (int pt = 0, dist; x; x = par[x], pt++)
            dist = anc[u][pt],
            A[x].upd(l - dist + 1, r - dist + 1, val);
        x = u;
        for (int pt = 1, dist; par[x]; x = par[x], pt++)
            dist = anc[u][pt],
            B[x].upd(l - dist + 1, r - dist + 1, val);
    }
    int qry(int x)
    {
        int ans = A[x].get(1);
        int u = x;
        for (int pt = 1, dist; par[x]; x = par[x], pt++)
            dist = anc[u][pt],
            ans += A[par[x]].get(dist + 1) - B[x].get(dist + 1);
        return ans;
    }
    sub45(int one)
    {
        solve(1, 0);
        for (int i = 1; i <= n; i++)
            reverse(anc[i].begin(), anc[i].end());
        for (int i = 1; i <= n; i++)
            upd(i, 0, 0, 0);
        mu[0] = 1;
        for (int i = 1; i <= n; i++)
            mu[i] = (mu[i - 1] * one) % mod;
        for (int j = 1; j <= q; j++)
        {
            int t = qr[j][0], x = qr[j][1], D = qr[j][2], val = qr[j][3];
            if (t == 1) upd(x, 0, D, 1);
            else
                cout << a[x] * mu[qry(x)] % mod << "\n";
        }
    }
};
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
//    freopen("GARDEN.inp", "r", stdin);
//    freopen("GARDEN.out", "w", stdout);
    cin >> n >> mod;
    for (int i = 1, u, v; i < n; i++)
        cin >> u >> v,
        adj[u].emplace_back(v),
        adj[v].emplace_back(u);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    cin >> q;
    set<int> vq;
    for (int i = 1; i <= q; i++)
    {
        cin >> qr[i][0];
        if (qr[i][0] == 1)
            cin >> qr[i][1] >> qr[i][2] >> qr[i][3], vq.emplace(qr[i][3]);
        else cin >> qr[i][1];
    }
    if (max(n, q) <= 1000){
        sub1 bruh;
    }
    else if (vq.size() == 1)
    {
        sub45 bruh(*vq.begin());
    } else
    {
        sub23 bruh;
    }
}
| # | 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... |