#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(x) x.begin(), x.end()
int n, L, q, seen[200001], level[200001], c[200001][18], dep[200001][18], sub[200001][18], h[200001];
vector<int> FACT, mem[9], adj[200001];
int lookup(int i, int n) {
if (mem[i].size() <= n) {
mem[i].reserve(n + 1);
while (mem[i].size() <= n) mem[i].emplace_back((ll) mem[i].back() * FACT[i] % L);
}
return mem[i][n];
}
int fast(int x, int n) {
if (not n) return 1;
int ret = fast(x, n >> 1);
ret = (ll) ret * ret % L;
if (n & 1) ret = (ll) ret * x % L;
return ret;
}
struct Int {
int x;
vector<int> cnt;
Int() : Int(1) {}
Int(int _x) : x(_x), cnt(FACT.size()) {
for (int i = FACT.size(); i--;) {
while (x % FACT[i] == 0) {
cnt[i]++;
x /= FACT[i];
}
}
}
operator int() const {
int ret = x;
for (int i = FACT.size(); i--;) {
// cerr << cnt[i] << endl;
ret = (ll) ret * lookup(i, cnt[i]) % L;
// cerr << "!\n";
}
return ret;
}
void operator*=(const Int &o) {
x = (ll) x * o.x % L;
for (int i = FACT.size(); i--;) cnt[i] += o.cnt[i];
}
void operator/=(const Int &o) {
x = (ll) x * fast(o.x, L - 2) % L;
for (int i = FACT.size(); i--;) cnt[i] -= o.cnt[i];
}
};
struct St {
int n;
vector<Int> st;
void init(int n) { st.resize((this->n = n) << 1, 1); }
void upd(int l, int r, const Int &v) {
for (l += n, r = min(r, n) + n; l < r; l >>= 1, r >>= 1) {
if (l & 1) st[l++] *= v;
if (r & 1) st[--r] *= v;
}
}
Int operator()(int i) {
// cerr << (int) st[n] << endl;
Int ret;
for (i += n; i; i >>= 1) {
ret *= st[i];
}
return ret;
}
} inc[200001];
vector<St> exc[200001];
int dfs(int i, int p = 0) {
int f = 0, f2 = 0;
for (int j: adj[i]) {
if (j != p) {
int fj = dfs(j, i);
f2 |= fj & f;
f |= fj;
}
}
level[i] = __builtin_ctz(++(f |= f2));
return f;
}
int dfs2(int i, int r, int p) {
c[i][level[r]] = r;
int mx = 0;
for (int k: adj[i]) {
if (k != p and not seen[k]) {
sub[k][level[r]] = sub[i][level[r]];
dep[k][level[r]] = dep[i][level[r]] + 1;
mx = max(mx, dfs2(k, r, i));
}
}
return mx + 1;
}
int main() {
cin >> n >> L;
for (int i = 2; i * i <= L; ++i) {
if (L % i == 0) {
FACT.emplace_back(i);
FACT.emplace_back(L / i);
}
}
sort(all(FACT));
FACT.erase(unique(all(FACT)), FACT.end());
if (FACT.empty()) FACT = {L};
for (int i = FACT.size(); i--;) mem[i] = {1};
for (int i = n; --i;) {
int a, b;
cin >> a >> b;
adj[a].emplace_back(b);
adj[b].emplace_back(a);
}
dfs(1);
int order[n];
iota(order, order + n, 1);
sort(order, order + n, [&] (int i, int j) { return level[i] > level[j]; });
for (int i: order) {
c[i][level[i]] = i;
int mx = 1;
for (int j: adj[i]) {
if (seen[j]) continue;
sub[j][level[i]] = exc[i].size();
dep[j][level[i]] = 1;
int mxj = dfs2(j, i, i) + 1;
mx = max(mx, mxj);
exc[i].emplace_back();
exc[i].back().init(mxj);
}
inc[i].init(mx);
seen[i] = true;
}
for (int i = 1; i <= n; ++i) cin >> h[i];
cin >> q;
while (q--) {
int t, x;
cin >> t >> x;
if (t == 1) {
int d, raw;
cin >> d >> raw;
Int w{raw};
for (int i = 18; i--;) {
if (not c[x][i] or dep[x][i] > d) continue;
inc[c[x][i]].upd(0, d - dep[x][i] + 1, w);
if (x != c[x][i]) exc[c[x][i]][sub[x][i]].upd(0, d - dep[x][i] + 1, w);
}
} else {
Int ans{h[x]}, inv;
for (int i = 18; i--;) {
if (not c[x][i]) continue;
ans *= inc[c[x][i]](dep[x][i]);
if (x != c[x][i]) inv *= exc[c[x][i]][sub[x][i]](dep[x][i]);
}
ans /= inv;
cout << (int) ans << endl;
}
}
}
# | 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... |