Submission #1320103

#TimeUsernameProblemLanguageResultExecution timeMemory
1320103miniobSumtree (INOI20_sumtree)C++20
100 / 100
725 ms66648 KiB
#include <bits/stdc++.h> using namespace std; vector<long long> graph[200007]; long long war[200007]; long long sil[500007]; long long odw[500007]; long long pre[200007]; long long post[200007]; long long ojc[200007]; long long odp[200007]; long long drz[1048580][2]; long long roz[200007]; long long gl[200007]; long long gora[200007]; long long poz[200007]; long long odw2[200007]; long long gleb[200007]; long long cz2 = 0; set<long long> secik; long long pot(long long liczba, long long wykladnik) { long long w = 1; while (wykladnik > 0) { if (wykladnik % 2 == 1) { w = (w * liczba) % 1000000007; } liczba = (liczba * liczba) % 1000000007; wykladnik /= 2; } return w; } long long cz = 0, zer = 0, wyn = 1; void dfs(long long cur, long long pop) { pre[cur] = cz; cz++; for(auto x : graph[cur]) { if(x != pop) { ojc[x] = cur; dfs(x, cur); } } post[cur] = cz; cz++; } void ustaw(long long gdzie, long long co, long long x) { gdzie += 524288; drz[gdzie][x] = co; gdzie /= 2; while(gdzie != 0) { //cout << gdzie << " " << co << " " << endl; drz[gdzie][x] = drz[2 * gdzie][x] + drz[2 * gdzie + 1][x]; gdzie /= 2; } } long long przedzial(long long curl, long long curr, long long l, long long r, long long cur, long long x) { if(l > curr || curl > r) { return 0; } else if(l <= curl && curr <= r) { //cout << cur << " " << curl << " " << curr << " " << l << " " << r << endl; return drz[cur][x]; } else { return przedzial(curl, (curl + curr) / 2, l, r, 2 * cur, x) + przedzial((curl + curr) / 2 + 1, curr, l, r, 2 * cur + 1, x); } } void policz(long long co) { if(odp[co] == 0) { zer--; } else if(odp[co] != -1) { wyn *= pot(odp[co], 1000000005); wyn %= 1000000007; } long long ilew = przedzial(0, 524287, pre[co] + 1, post[co], 1, 0) + 1; long long iles = war[co] - przedzial(0, 524287, pre[co] + 1, post[co], 1, 1); //cout << pre[co] << " " << post[co] << " " << ilew << " " << iles << endl; if(iles < 0) { zer++; odp[co] = 0; return; } odp[co] = (((sil[ilew + iles - 1] * odw[ilew - 1]) % 1000000007) * odw[iles]) % 1000000007; wyn *= odp[co]; wyn %= 1000000007; return; } void dfs1(long long cur, long long pop) { roz[cur] = 1; gl[cur] = 0; for(auto x : graph[cur]) { if(x != pop) { gleb[x] = gleb[cur] + 1; dfs1(x, cur); roz[cur] += roz[x]; if(gl[cur] == 0 || roz[x] > roz[gl[cur]]) { gl[cur] = x; } } } } void dfs2(long long cur, long long curg) { gora[cur] = curg; cz2++; poz[cur] = cz2; odw2[cz2] = cur; if(gl[cur] != 0) { dfs2(gl[cur], curg); } for(auto x : graph[cur]) { if(x != ojc[cur] && x != gl[cur]) { dfs2(x, x); } } } long long znajdz(long long x) { while(x != 0) { auto it = secik.upper_bound(poz[x]); if(it != secik.begin()) { it--; if(*it >= poz[gora[x]]) { return odw2[*it]; } } x = ojc[gora[x]]; } return 1; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); sil[0] = 1; odw[0] = 1; for(long long i = 1; i <= 500005; i++) { sil[i] = sil[i - 1] * i; sil[i] %= 1000000007; } for(long long i = 1; i <= 500005; i++) { odw[i] = pot(sil[i], 1000000005); } long long n, r, q; cin >> n >> r; for(long long i = 0; i <= n; i++) { war[i] = -1; odp[i] = -1; } war[1] = r; odp[1] = (((sil[n + r - 1] * odw[n - 1]) % 1000000007) * odw[r]) % 1000000007; wyn = odp[1]; for(long long i = 0; i < n - 1; i++) { long long a, b; cin >> a >> b; graph[a].push_back(b); graph[b].push_back(a); } cin >> q; dfs(1, 0); gleb[1] = 0; dfs1(1, 0); dfs2(1, 1); secik.insert(poz[1]); for(long long i = 1; i <= n; i++) { ustaw(pre[i], 1, 0); //cout << pre[i] << endl; } cout << wyn << endl; while(q--) { long long a, b, c; cin >> a >> b; if(a == 2) { if(odp[b] == 0) { zer--; } else { wyn *= pot(odp[b], 1000000005); wyn %= 1000000007; } odp[b] = -1; ustaw(pre[b], 1, 0); ustaw(pre[b], 0, 1); secik.erase(poz[b]); war[b] = -1; b = znajdz(ojc[b]); policz(b); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 0), 0); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 1) + war[b], 1); if(zer > 0) { cout << 0 << endl; } else { cout << wyn << endl; } } else { cin >> c; war[b] = c; secik.insert(poz[b]); policz(b); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 0), 0); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 1) + war[b], 1); //cout << odp[b] << endl; b = znajdz(ojc[b]); policz(b); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 0), 0); ustaw(pre[b], -przedzial(0, 524287, pre[b] + 1, post[b], 1, 1) + war[b], 1); if(zer > 0) { cout << 0 << endl; } else { cout << wyn << endl; } } } return 0; }
#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...