#include <bits/stdc++.h>
#define FOR(i, x, n) for(int i = x; i < n; i++)
#define F0R(i, n) FOR(i, 0, n)
#define ROF(i, x, n) for(int i = n - 1; i >= x; i--)
#define R0F(i, n) ROF(i, 0, n)
#define WTF cout << "WTF" << endl
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define F first
#define S second
#define PB push_back
#define ALL(x) x.begin(), x.end()
#define RALL(x) x.rbegin(), x.rend()
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<int> VI;
typedef vector<LL> VLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
const int N = 5e5 + 7;
const int LOG = 22;
const int INF = 1e9 + 7;
const int MOD = 1e9 + 7;
#define lc now << 1
#define rc now << 1 | 1
#define endl '\n'
LL chs[N], vir[N], fact[N], ifact[N];
LL ans;
VI adj[N], order;
int n, q, bad, cnt;
int head[N], ns[N], par[N], s[N], height[N];
int t[N][2];
struct SumTree {
LL tree[N << 2];
void build(int now = 1, int ls = 0, int rs = n - 1) {
if (ls == rs) {
tree[now] = s[ls];
return;
}
int mid = (ls + rs) >> 1;
build(lc, ls, mid);
build(rc, mid + 1, rs);
return;
}
void add(int lq, int rq, LL val, int now = 1, int ls = 0, int rs = n - 1) {
//cout << "ls rs " << ls << ' ' << rs << endl;
if (rq < lq || rq < ls || rs < lq) return;
if (lq <= ls && rs <= rq) {
tree[now] += val;
return;
}
int mid = (ls + rs) >> 1;
add(lq, rq, val, lc, ls, mid);
add(lq, rq, val, rc, mid + 1, rs);
return;
}
LL get(int id, int now = 1, int ls = 0, int rs = n - 1) {
if (ls == rs) return tree[now];
int mid = (ls + rs) >> 1;
if (id <= mid) return get(id, lc, ls, mid) + tree[now];
return get(id, rc, mid + 1, rs) + tree[now];
}
} val, sz;
struct DescendTree {
bool tree[N << 2];
bool arr[N];
void ch(int id, bool val, int now = 1, int ls = 0, int rs = n - 1) {
if (ls == rs) {
tree[now] = val;
return;
}
int mid = (ls + rs) >> 1;
if (ls <= mid) ch(id, val, lc, ls, mid);
else ch(id, val, rc, mid + 1, rs);
tree[now] = tree[lc] | tree[rc];
}
void change(int id, int val) {
ch(id, val);
arr[id] = val;
}
int g(int x) {
return arr[x];
}
int rightest(int q, int now = 1, int ls = 0, int rs = n - 1) {
if (ls >= q || !tree[now]) return n;
if (ls == rs) return ls;
int mid = (ls + rs) >> 1;
int case1 = rightest(q, rc, mid + 1, rs);
return (case1 == n ? rightest(q, lc, ls, mid) : case1);
}
} active;
inline int pw(LL a, int b) {
LL ret = 1;
for(; b; b >>= 1, a = a * a % MOD)
if (b & 1) ret = ret * a % MOD;
return ret;
}
inline int nCr(int nn, int rr) {
if (nn < rr || rr < 0) return 0;
return (fact[nn] * ifact[rr] % MOD) * ifact[nn - rr] % MOD;
}
void init() {
LL v0;
cin >> n >> v0;
//cout << "----------" << endl;
val.add(0, 0, v0);
//cout << "val.add(0, 0, " << v0 << ")" << endl;
F0R(i, n - 1) {
int u, v;
cin >> u >> v;
adj[--u].PB(--v);
adj[v].PB(u);
}
cin >> q;
ans = 1;
return;
}
void preD(int now, int p) {
par[now] = p;
s[now] = 1;
for(int on : adj[now]) if (on != p) {
preD(on, now);
s[now] += s[on];
}
return;
}
void precalc() {
fact[0] = 1;
FOR(i, 1, N) fact[i] = fact[i - 1] * i % MOD;
ifact[N - 1] = pw(fact[N - 1], MOD - 2);
R0F(i, N - 1) ifact[i] = ifact[i + 1] * (i + 1) % MOD;
iota(head, head + n, 0);
F0R(i, n) {
sort(ALL(adj[i]), [](const int &a, const int &b) {return s[a] < s[b];});
if (i) adj[i].pop_back();
reverse(ALL(adj[i]));
}
return;
}
void dfs(int now) {
order.PB(now);
t[now][0] = cnt++;
if (!adj[now].empty()) head[ adj[now][0] ] = head[now];
for(int on : adj[now]) dfs(on);
t[now][1] = cnt;
return;
}
void updChoose(int now) {
if (!chs[now]) bad--;
else ans = (ans * pw(chs[now], MOD - 2)) % MOD;
LL val_now = val.get(now);
LL sz_now = sz.get(now);
chs[now] = nCr(val_now + sz_now - 1, sz_now - 1);
if (!chs[now]) bad++;
else ans = (ans * chs[now]) % MOD;
return;
}
void remChoose(int now) {
if (!chs[now]) bad--;
else ans = (ans * pw(chs[now], MOD - 2)) % MOD;
chs[now] = 1;
return;
}
int getUpperActive(int v) {
while(!active.g(v)) {
int pl = active.rightest(t[v][0]);
if (t[pl] >= t[ head[v] ]) v = pl;
else v = par[ head[v] ];
}
return v;
}
void addUpTo(int v, int z, int x1, LL x2) {
//cout << "z = " << z << endl;
while(height[v] >= height[z]) {
int w = (height[ head[v] ] >= height[z] ? head[v] : z);
sz.add(t[w][0], t[v][0], x1);
val.add(t[w][0], t[v][0], x2);
v = par[w];
//cout << "v = " << v << endl;
}
return;
}
void addTag() {
int v, x;
cin >> v >> x;
v--;
val.add(v, v, x);
int sz_v = sz.get(v);
LL val_v = val.get(v);
int up = getUpperActive(v);
addUpTo(par[v], up, -sz_v, -val_v);
vir[v] = x;
updChoose(up);
updChoose(v);
active.change(v, 1);
return;
}
void remTag() {
int v;
cin >> v;
v--;
int sz_v = sz.get(v);
int val_v = val.get(v);
int up = getUpperActive(par[v]);
addUpTo(par[v], up, sz_v, val_v);
val.add(v, v, -vir[v]);
updChoose(up);
remChoose(v);
active.change(v, 0);
return;
}
int main() {
IOS;
init();
height[n] = -1;
par[0] = n;
preD(0, n);
precalc();
dfs(0);
sz.build();
active.change(0, 1);
fill(chs, chs + n, 1);
updChoose(0);
cout << ans << endl;
while(q--) {
int tp; cin >> tp;
if (tp == 1) addTag();
else remTag();
cout << (bad ? 0 : ans) << endl;
}
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
174 ms |
43736 KB |
Output is correct |
2 |
Correct |
195 ms |
43844 KB |
Output is correct |
3 |
Correct |
187 ms |
43808 KB |
Output is correct |
4 |
Correct |
208 ms |
43896 KB |
Output is correct |
5 |
Correct |
188 ms |
39872 KB |
Output is correct |
6 |
Correct |
21 ms |
20484 KB |
Output is correct |
7 |
Correct |
19 ms |
20240 KB |
Output is correct |
8 |
Correct |
21 ms |
20180 KB |
Output is correct |
9 |
Correct |
223 ms |
36140 KB |
Output is correct |
10 |
Correct |
163 ms |
36084 KB |
Output is correct |
11 |
Correct |
202 ms |
36180 KB |
Output is correct |
12 |
Correct |
206 ms |
35480 KB |
Output is correct |
13 |
Correct |
152 ms |
42464 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
3060 ms |
19868 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
230 ms |
94320 KB |
Execution killed with signal 11 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
3019 ms |
40308 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
174 ms |
43736 KB |
Output is correct |
2 |
Correct |
195 ms |
43844 KB |
Output is correct |
3 |
Correct |
187 ms |
43808 KB |
Output is correct |
4 |
Correct |
208 ms |
43896 KB |
Output is correct |
5 |
Correct |
188 ms |
39872 KB |
Output is correct |
6 |
Correct |
21 ms |
20484 KB |
Output is correct |
7 |
Correct |
19 ms |
20240 KB |
Output is correct |
8 |
Correct |
21 ms |
20180 KB |
Output is correct |
9 |
Correct |
223 ms |
36140 KB |
Output is correct |
10 |
Correct |
163 ms |
36084 KB |
Output is correct |
11 |
Correct |
202 ms |
36180 KB |
Output is correct |
12 |
Correct |
206 ms |
35480 KB |
Output is correct |
13 |
Correct |
152 ms |
42464 KB |
Output is correct |
14 |
Execution timed out |
3060 ms |
19868 KB |
Time limit exceeded |
15 |
Halted |
0 ms |
0 KB |
- |