#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
vector<ll> graph[200003];
ll fat[200003];
ll label[200003];
ll dep[200003];
ll id[200003];
ll seg_id[200003];
ll prep_siz[200003];
vector<ll> whole_path[200003];
vector<set<pair<ll, ll>>> tagged_on_path(1);
ll iter, seg_iter;
inline array<ll, 2> operator+(const array<ll, 2> &a, const array<ll, 2> &b)
{
return {a[0] + b[0], a[1] + b[1]};
}
inline array<ll, 2> &operator+=(array<ll, 2> &a, const array<ll, 2> &b)
{
a[0] += b[0];
a[1] += b[1];
return a;
}
const ll base = 1 << 18;
array<ll, 2> tree[2 * base];
void add(ll a, ll b, array<ll, 2> x)
{
a += base - 1;
b += base + 1;
while (a / 2 != b / 2)
{
if (!(a & 1))
tree[a + 1] += x;
if (b & 1)
tree[b - 1] += x;
a >>= 1;
b >>= 1;
}
}
array<ll, 2> query(ll v)
{
v += base;
array<ll, 2> ans{};
while (v)
{
ans += tree[v];
v >>= 1;
}
return ans;
}
void path_add(ll v, array<ll, 2> x)
{
if (v == 0)
return;
add(seg_id[whole_path[id[v]][0]], seg_id[v], x);
path_add(fat[whole_path[id[v]][0]], x);
}
void path_add(ll v, ll p, array<ll, 2> x)
{
path_add(v, x);
path_add(fat[p], {-x[0], -x[1]});
}
array<ll, 2> val(ll v)
{
return query(seg_id[v]);
}
void prep(ll v, ll p)
{
fat[v] = p;
prep_siz[v] = 1;
for (auto u : graph[v])
{
if (u == p)
continue;
dep[u] = dep[v] + 1;
prep(u, v);
prep_siz[v] += prep_siz[u];
}
sort(graph[v].begin(), graph[v].end(), [&](ll x, ll y)
{ return prep_siz[x] > prep_siz[y]; });
}
void dfs(ll v, ll p, ll ind)
{
id[v] = ind;
seg_id[v] = ++seg_iter;
tree[seg_iter + base] = {prep_siz[v], 0};
whole_path[ind].push_back(v);
for (auto u : graph[v])
{
if (u == p)
continue;
if (2 * prep_siz[u] > prep_siz[v])
dfs(u, v, ind);
else
{
tagged_on_path.push_back({});
dfs(u, v, ++iter);
}
}
}
ll fact[500003];
ll fact_inv[500003];
ll fast_pow(ll a, ll b)
{
if (b == 1)
return a;
ll cur = fast_pow(a, b / 2);
cur = (cur * cur) % mod;
if (b & 1)
cur = (cur * a) % mod;
return cur;
}
void init(ll &n, ll &r, ll &q)
{
cin >> n >> r;
for (ll i = 1, a, b; i < n; i++)
{
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
cin >> q;
fact[0] = 1;
for (ll i = 1; i <= 500002; i++)
fact[i] = (i * fact[i - 1]) % mod;
fact_inv[500002] = fast_pow(fact[500002], mod - 2);
for (ll i = 500001; i >= 0; i--)
fact_inv[i] = ((i + 1) * fact_inv[i + 1]) % mod;
}
ll res(ll siz, ll tag)
{
ll wyn = fact[siz + tag - 1];
wyn = (wyn * fact_inv[tag]) % mod;
wyn = (wyn * fact_inv[siz - 1]) % mod;
return wyn;
}
ll Find(ll v)
{
if (tagged_on_path[id[v]].empty() || ((*tagged_on_path[id[v]].begin()).first > dep[v]))
return Find(fat[whole_path[id[v]][0]]);
return prev(tagged_on_path[id[v]].lower_bound({dep[v] + 1, -1}))->second;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
ll n, q;
init(n, label[1], q);
if (n == 1)
{
for (ll i = 0; i < q + 1; i++)
{
cout << "1\n";
}
return 0;
}
prep(1, 0);
dfs(1, 0, 0);
ll ans = res(n, label[1]), neg_vert = 0;
cout << ans << '\n';
tagged_on_path[id[1]].insert({dep[1], 1});
auto modify_ans = [&](ll siz, ll lab, ll inv) -> void
{
if (lab < 0)
{
neg_vert += inv;
return;
}
if (inv == 1)
ans = (ans * res(siz, lab)) % mod;
else
ans = (ans * fast_pow(res(siz, lab), mod - 2)) % mod;
};
for (ll i = 1, t, v, tag; i <= q; i++)
{
cin >> t >> v;
if (t == 1)
cin >> tag;
ll up = Find(fat[v]);
array<ll, 2> v_info = val(v), up_info = val(up);
modify_ans(up_info[0], up_info[1] + label[up], -1);
if (t == 1)
{
label[v] = tag;
modify_ans(v_info[0], v_info[1] + label[v], 1);
tagged_on_path[id[v]].insert({dep[v], v});
path_add(fat[v], up, array<ll, 2>{-v_info[0], -label[v] - v_info[1]});
}
else
{
path_add(fat[v], up, array<ll, 2>{v_info[0], label[v] + v_info[1]});
tagged_on_path[id[v]].erase({dep[v], v});
modify_ans(v_info[0], v_info[1] + label[v], -1);
label[v] = 0;
}
up_info = val(up);
modify_ans(up_info[0], up_info[1] + label[up], 1);
cout << (neg_vert ? 0 : 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... |