結果
問題 | No.2439 Fragile Apple Tree |
ユーザー | kenken714 |
提出日時 | 2023-08-11 19:37:39 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2,113 ms / 10,000 ms |
コード長 | 7,951 bytes |
コンパイル時間 | 3,154 ms |
コンパイル使用メモリ | 224,720 KB |
実行使用メモリ | 90,240 KB |
最終ジャッジ日時 | 2024-11-22 12:47:47 |
合計ジャッジ時間 | 34,301 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 944 ms
74,752 KB |
testcase_01 | AC | 1,650 ms
76,928 KB |
testcase_02 | AC | 1,618 ms
76,928 KB |
testcase_03 | AC | 703 ms
90,240 KB |
testcase_04 | AC | 1,025 ms
90,240 KB |
testcase_05 | AC | 1,486 ms
76,928 KB |
testcase_06 | AC | 1,625 ms
76,928 KB |
testcase_07 | AC | 2,111 ms
77,440 KB |
testcase_08 | AC | 2,113 ms
77,568 KB |
testcase_09 | AC | 41 ms
56,320 KB |
testcase_10 | AC | 41 ms
56,448 KB |
testcase_11 | AC | 42 ms
56,320 KB |
testcase_12 | AC | 41 ms
56,320 KB |
testcase_13 | AC | 42 ms
56,320 KB |
testcase_14 | AC | 2,084 ms
76,416 KB |
testcase_15 | AC | 1,116 ms
76,928 KB |
testcase_16 | AC | 1,560 ms
77,056 KB |
testcase_17 | AC | 1,515 ms
76,928 KB |
testcase_18 | AC | 617 ms
74,240 KB |
testcase_19 | AC | 582 ms
65,408 KB |
testcase_20 | AC | 257 ms
63,488 KB |
testcase_21 | AC | 133 ms
56,576 KB |
testcase_22 | AC | 949 ms
67,328 KB |
testcase_23 | AC | 451 ms
61,440 KB |
testcase_24 | AC | 519 ms
64,384 KB |
testcase_25 | AC | 419 ms
70,528 KB |
testcase_26 | AC | 516 ms
72,960 KB |
testcase_27 | AC | 407 ms
66,304 KB |
testcase_28 | AC | 42 ms
56,448 KB |
testcase_29 | AC | 41 ms
56,448 KB |
testcase_30 | AC | 42 ms
56,320 KB |
testcase_31 | AC | 1,007 ms
78,156 KB |
testcase_32 | AC | 992 ms
78,024 KB |
ソースコード
#include "bits/stdc++.h" using namespace std; #define REP(i, n) for(ll i = 0;i < n;i++) #define REPR(i, n) for(ll i = n;i >= 0;i--) #define FOR(i, m, n) for(ll i = m;i < n;i++) #define FORR(i, m, n) for(ll i = m;i >= n;i--) #define REPO(i, n) for(ll i = 1;i <= n;i++) #define ll long long #define INF (ll)1ll << 60 #define MINF (-1 * INF) #define ALL(n) n.begin(),n.end() #define MOD (ll)1000000007 struct LazySegTree { //参照は i + sz - 1 ll sz; vector<ll> node, lazy; vector<bool> lazyFlag; LazySegTree(ll n) { sz = 1; while (sz < n) sz *= 2; node.resize(2 * sz - 1, INF);// lazy.resize(2 * sz - 1);// lazyFlag.resize(2 * sz - 1); } void eval(ll k, ll l, ll r) { if (lazyFlag[k]) { node[k] += lazy[k];// if (r - l > 1) { lazy[2 * k + 1] += lazy[k];// lazy[2 * k + 2] += lazy[k];// lazyFlag[2 * k + 1] = lazyFlag[2 * k + 2] = true; } lazyFlag[k] = false; lazy[k] = 0;// } } void update(ll a, ll b, ll x, ll k = 0, ll l = 0, ll r = -1) { if (r < 0) r = sz; eval(k, l, r); if (b <= l || r <= a) return; if (a <= l && r <= b) { lazy[k] = x;// lazyFlag[k] = true; eval(k, l, r); } else { update(a, b, x, 2 * k + 1, l, (l + r) / 2); update(a, b, x, 2 * k + 2, (l + r) / 2, r); node[k] = min(node[2 * k + 1], node[2 * k + 2]);// } } void update(ll a, ll x) { update(a, a + 1, x); } ll query(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) { if (r < 0) r = sz; eval(k, l, r); if (b <= l || r <= a) return INF;// if (a <= l && r <= b) return node[k]; ll vl = query(a, b, 2 * k + 1, l, (l + r) / 2); ll vr = query(a, b, 2 * k + 2, (l + r) / 2, r); return min(vl, vr);// } int nibutan_query(ll a, ll b){ ll res = nibutan(a, b); return (res == a - 1) ? -1 : res; } ll nibutan(ll a, ll b, ll k = 0, ll l = 0, ll r = -1) { if (r < 0) r = sz; eval(k, l, r); if (node[k] > 0 or r <= a or b <= l) { return a - 1; } else if (r - l == 1) { return (k - (sz - 1)); } else { int vr = nibutan(a, b, 2 * k + 2, (l + r) / 2, r); if (vr != a - 1) { return vr; } else { return nibutan(a, b, 2 * k + 1, l, (l + r) / 2); } } } void init() { REPR(i, sz - 2) node[i] = min(node[2 * i + 1], node[2 * i + 2]);// } }; struct SegTree { ll sz; vector<ll> dat; SegTree(ll n) { sz = 1; while (sz < n)sz *= 2; dat.resize(2 * sz - 1, 0);// } void update(ll a, ll b, ll x, ll k = 0, ll l = 0, ll r = -1) { if (r < 0) r = sz; if (r <= a or b <= l)return;// if (a <= l and r <= b) { dat[k] += x; return; } // ll q1, q2; update(a, b, x, k * 2 + 1, l, (l + r) / 2); update(a, b, x, k * 2 + 2, (l + r) / 2, r); } ll query(ll a){ a += sz - 1; ll res = 0; do{ res += dat[a]; a = (a - 1) / 2; } while (a > 0); return res; } }; struct HLD { vector<ll> g[510000]; vector<ll> sz, in, out, head, rev, par, dep; //rev = in -> index HLD(ll n) : sz(n), in(n), out(n), head(n), rev(n), par(n), dep(n) {}; void dfs_sz(ll a, ll p, ll b) { par[a] = p; sz[a] = 1; dep[a] = b; if (g[a].size() && g[a][0] == p) swap(g[a][0], g[a].back()); for (auto& to : g[a]) { if (to == p)continue; dfs_sz(to, a, b + 1); sz[a] += sz[to]; if (sz[g[a][0]] < sz[to])swap(g[a][0], to); } } void dfs_hld(ll a, ll p, ll& t) { in[a] = t++; rev[in[a]] = a; for (auto& to : g[a]) { if (to == p)continue; head[to] = (g[a][0] == to ? head[a] : to); dfs_hld(to, a, t); } out[a] = t; } void edgeset(ll a, ll b) { g[a].push_back(b); g[b].push_back(a); } void build() { dfs_sz(0, -1, 0); ll t = 0; dfs_hld(0, -1, t); } void input(ll n) { REP(i, n - 1) { ll a, b; cin >> a >> b; a--; b--; edgeset(a, b); } build(); } ll la(ll a, ll x) { while (1) { ll h = head[a]; if (in[a] - x >= in[h])return rev[in[a] - x]; x -= in[a] - in[h] + 1; a = par[h]; } } ll lca(ll a, ll b) { for (;; b = par[head[b]]) { if (in[a] > in[b])swap(a, b); if (head[a] == head[b])return a; } } template< typename Q, typename F > ll query(ll a, ll b, ll ti, const Q& q, const F& f, bool edge = false) { ll l = ti, r = ti; for (;; b = par[head[b]]) { if (in[a] > in[b])swap(a, b), swap(l, r); if (head[a] == head[b])break; l = f(q(in[head[b]], in[b] + 1), l); } return f(f(q(in[a] + edge, in[b] + 1), l), r); } template< typename Q > ll nibutan(ll a, ll b, const Q& q, bool edge = false) { for (;; b = par[head[b]]) { if (in[a] > in[b]) swap(a, b); if (head[a] == head[b])break; ll res = q(in[head[b]], in[b] + 1); if (res != -1) return rev[res]; } ll res = q(in[a] + edge, in[b] + 1); if(res != -1)return rev[res]; return -1; } template < typename Q > void addpath(ll a, ll b, ll x, const Q& q, bool edge = false) { //path for (;; b = par[head[b]]) { if (in[a] > in[b])swap(a, b); if (head[a] == head[b])break; q(in[head[b]], in[b] + 1, x); } return q(in[a] + edge, in[b] + 1, x); } template < typename Q > void addst(ll a, ll x, const Q& q) { //subtree q(in[a], out[a], x); } }; int ans; LazySegTree seg(300010); SegTree seg2(300010); HLD hld(300010); struct Edge{ ll a, b, c; }; vector<Edge> edges; vector<ll> init_c; int main(){ ll N, Q; cin >> N >> Q; ans = N; edges.resize(N - 1); init_c.resize(N); for(int i = 0; i < N - 1; i++){ cin >> edges[i].a >> edges[i].b >> edges[i].c; edges[i].a--; edges[i].b--; hld.edgeset(edges[i].a, edges[i].b); } hld.build(); //init for (int i = 0; i < N - 1; i++){ if(hld.dep[edges[i].a] > hld.dep[edges[i].b]) swap(edges[i].a, edges[i].b); seg.node[hld.in[edges[i].b] + seg.sz - 1] = edges[i].c; init_c[edges[i].b] = edges[i].c; } init_c[0] = INF; seg.node[hld.in[0] + seg.sz - 1] = INF; seg.init(); for(int i = 0; i < N; i++){ seg2.dat[hld.in[i] + seg2.sz - 1] = hld.sz[i]; } for(int i = 0; i < Q; i++){ ll type; cin >> type; if(type == 1){ ll v, x; cin >> v >> x; v--; hld.addpath(0, v, -x, [](ll a, ll b, ll x){seg.update(a, b, x);}); ll w = hld.nibutan(0, v, [](ll a, ll b){return seg.nibutan_query(a, b);}); if(w == -1)continue; ll subtree_sz = seg2.query(hld.in[w]); ans -= subtree_sz; hld.addpath(0, hld.par[w], -subtree_sz, [](ll a, ll b, ll x){seg2.update(a, b, x);}); ll w_apple = init_c[w] - hld.query(w, w, 0, [](ll a, ll b){return seg.query(a, b);}, [](ll a, ll b){return min(a, b);}); hld.addpath(0, w, w_apple, [](ll a, ll b, ll x){seg.update(a, b, x);}); } if(type == 2){ cout << ans << endl; } } }