답안 #469371

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
469371 2021-08-31T16:04:20 Z sinamhdv Sumtree (INOI20_sumtree) C++11
10 / 100
837 ms 54968 KB
// INOI20_sumtree
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod = 1000 * 1000 * 1000 + 7;
const int INF = 1e9 + 100;
const ll LINF = 1e18 + 100;

#ifdef DEBUG
#define dbg(x) cout << #x << " = " << (x) << endl << flush;
#define dbgr(s, f) { cout << #s << ": "; for (auto _ = (s); _ != (f); _++) cout << *_ << ' '; cout << endl << flush; }
#else
#define dbg(x) ;
#define dbgr(s, f) ;
#endif
#define fast_io ios::sync_with_stdio(0); cin.tie(0);
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define fr first
#define sc second
#define endl '\n'

const int MAXN = 200100;
const int MAXF = 500100;
const int LOGN = 25;

inline int poww(int a, int b)
{
	int res = 1;
	for (; b; a = (ll)a * a % mod, b /= 2) if (b & 1) res = (ll)res * a % mod;
	return res;
}

int n, rt, q;
vector<int> adj[MAXN];
int bad, ans;
int sttime[MAXN], fntime[MAXN], timer, h[MAXN];
int lbl[MAXN], val[MAXN], cnt[MAXN];
int lpar[LOGN][MAXN];
int fact[MAXF], finv[MAXF];

inline int comb(int n, int k)
{
	return (fact[n] * (ll)finv[k] % mod) * finv[n - k] % mod;
}

void dfs1(int v)
{
	sttime[v] = timer++;
	for (int u : adj[v]) if (u != lpar[0][v])
	{
		lpar[0][u] = v;
		h[u] = h[v] + 1, dfs1(u);
	}
	fntime[v] = timer;
}

struct FEN
{
	ll fen[MAXN];

	inline void addind(int i, ll x)
	{
		for (i++; i < MAXN; i += i & -i) fen[i] += x;
	}

	inline ll pget(int i)
	{
		ll res = 0;
		for (i++; i > 0; i -= i & -i) res += fen[i];
		return res;
	}

	inline ll get(int l, int r)
	{
		if (l > r) return 0;
		return pget(r) - pget(l - 1);
	}

	inline void add(int l, int r, ll x)
	{
		addind(l, x);
		addind(r + 1, -x);
	}

} valfen, ancfen;

struct node
{
	int mn, mincnt, lz;
};

struct SEG
{
	node seg[4 * MAXN];

	inline node mrg(const node &lc, const node &rc)
	{
		node res = {};
		res.mn = min(lc.mn, rc.mn);
		res.mincnt = 0;
		if (lc.mn == res.mn) res.mincnt += lc.mincnt;
		if (rc.mn == res.mn) res.mincnt += rc.mincnt;
		return res;
	}

	inline void pushdown(int v)
	{
		if (seg[v].lz == -1) return;
		FOR(t, 2 * v, 2 * v + 2)
		{
			if (seg[t].mn == seg[v].mn) seg[t].mn = seg[t].lz = seg[v].lz;
		}
		seg[v].lz = -1;
	}

	void build(int v = 1, int l = 0, int r = n - 1)
	{
		if (l == r)
		{
			seg[v] = {0, 1, -1};
			return;
		}
		int mid = (r + l) / 2;
		build(2 * v, l, mid);
		build(2 * v + 1, mid + 1, r);
		seg[v] = mrg(seg[2 * v], seg[2 * v + 1]);
		seg[v].lz = -1;
	}

	void rset(int L, int R, int x, int v = 1, int l = 0, int r = n - 1)
	{
		if (l > R || r < L) return;
		if (l >= L && r <= R)
		{
			seg[v].mn = seg[v].lz = x;
			return;
		}
		int mid = (r + l) / 2;
		pushdown(v);
		rset(L, R, x, 2 * v, l, mid);
		rset(L, R, x, 2 * v + 1, mid + 1, r);
		seg[v] = mrg(seg[2 * v], seg[2 * v + 1]);
	}

	node getmin(int L, int R, int v = 1, int l = 0, int r = n - 1)
	{
		if (l > R || r < L) return {INF, 0, 0};
		if (l >= L && r <= R) return seg[v];
		int mid = (r + l) / 2;
		pushdown(v);
		return mrg(getmin(L, R, 2 * v, l, mid), getmin(L, R, 2 * v + 1, mid + 1, r));
	}

} seg;

inline int getpar(int x, int d)
{
	FOR(i, 0, LOGN) if (d >> i & 1) x = lpar[i][x];
	return x;
}

inline void addans(int i)
{
	if (val[i] < 0) bad++;
	else ans = (ll)ans * comb(val[i] + cnt[i] - 1, cnt[i] - 1) % mod;
}

inline void remans(int i)
{
	if (val[i] < 0) bad--;
	else ans = (ll)ans * poww(comb(val[i] + cnt[i] - 1, cnt[i] - 1), mod - 2) % mod;
}

inline void updateval(int v)
{
	ll nw = lbl[v] - valfen.get(sttime[v] + 1, fntime[v] - 1);
	valfen.addind(sttime[v], nw - val[v]);
	val[v] = nw;
}

inline int findanc(int v)
{
	int l = 0, r = h[v] + 1;
	int cur = ancfen.pget(sttime[v]);
	while (r - l > 1)
	{
		int mid = (r + l) / 2;
		int x = getpar(v, mid);
		if (ancfen.pget(sttime[x]) == cur) l = mid;
		else r = mid;
	}
	return getpar(v, l);
}

int32_t main(void)
{
	fast_io;

	fact[0] = 1;
	FOR(i, 1, MAXF) fact[i] = fact[i - 1] * (ll)i % mod;
	finv[MAXF - 1] = poww(fact[MAXF - 1], mod - 2);
	for (int i = MAXF - 2; i >= 0; i--) finv[i] = (ll)finv[i + 1] * (i + 1) % mod;

	cin >> n >> rt;
	FOR(i, 0, n - 1)
	{
		int x, y;
		cin >> x >> y;
		adj[x].pb(y);
		adj[y].pb(x);
	}

	dfs1(1);

	FOR(i, 1, LOGN) FOR(j, 1, n + 1) lpar[i][j] = lpar[i - 1][lpar[i - 1][j]];

	ans = comb(n + rt - 1, n - 1);
	cout << ans << endl;
	ancfen.add(0, n - 1, 1);
	lbl[1] = val[1] = rt;
	cnt[1] = n;
	seg.build();

	cin >> q;
	while (q--)
	{
		int op, v;
		cin >> op >> v;
		if (op == 1)	// add
		{
			int x;
			cin >> x;
			lbl[v] = x;

			// update anc
			int l = findanc(v);
			ancfen.add(sttime[v], fntime[v] - 1, 1);

			remans(l);

			// update cnt
			int c = seg.getmin(sttime[v], fntime[v] - 1).mincnt;
			seg.rset(sttime[v], fntime[v] - 1, sttime[v]);
			cnt[l] -= c;
			cnt[v] += c;

			// update val
			updateval(v);
			updateval(l);

			addans(v);
			addans(l);
		}
		else	// rem
		{
			ancfen.add(sttime[v], fntime[v] - 1, -1);
			int l = findanc(v);

			remans(l);
			remans(v);

			int c = seg.getmin(sttime[v], fntime[v] - 1).mincnt;
			seg.rset(sttime[v], fntime[v] - 1, sttime[l]);
			cnt[l] += c;
			cnt[v] = 0;

			valfen.addind(sttime[v], -val[v]);
			lbl[v] = val[v] = 0;
			updateval(l);

			addans(l);
		}

		ans = (mod + ans % mod) % mod;
		if (bad) cout << "0\n";
		else cout << ans << endl;
	}

	return 0;
}


# 결과 실행 시간 메모리 Grader output
1 Correct 152 ms 50164 KB Output is correct
2 Correct 156 ms 50148 KB Output is correct
3 Correct 161 ms 50200 KB Output is correct
4 Correct 172 ms 50104 KB Output is correct
5 Correct 155 ms 46912 KB Output is correct
6 Correct 14 ms 9800 KB Output is correct
7 Correct 13 ms 9664 KB Output is correct
8 Correct 13 ms 9676 KB Output is correct
9 Correct 156 ms 44100 KB Output is correct
10 Correct 178 ms 43992 KB Output is correct
11 Correct 160 ms 44036 KB Output is correct
12 Correct 163 ms 42744 KB Output is correct
13 Correct 139 ms 47436 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 12 ms 9164 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 213 ms 54968 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 837 ms 50032 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 152 ms 50164 KB Output is correct
2 Correct 156 ms 50148 KB Output is correct
3 Correct 161 ms 50200 KB Output is correct
4 Correct 172 ms 50104 KB Output is correct
5 Correct 155 ms 46912 KB Output is correct
6 Correct 14 ms 9800 KB Output is correct
7 Correct 13 ms 9664 KB Output is correct
8 Correct 13 ms 9676 KB Output is correct
9 Correct 156 ms 44100 KB Output is correct
10 Correct 178 ms 43992 KB Output is correct
11 Correct 160 ms 44036 KB Output is correct
12 Correct 163 ms 42744 KB Output is correct
13 Correct 139 ms 47436 KB Output is correct
14 Incorrect 12 ms 9164 KB Output isn't correct
15 Halted 0 ms 0 KB -