結果
問題 | No.399 動的な領主 |
ユーザー | rokahikou1 |
提出日時 | 2021-02-04 19:37:07 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,124 ms / 2,000 ms |
コード長 | 8,673 bytes |
コンパイル時間 | 2,489 ms |
コンパイル使用メモリ | 197,740 KB |
実行使用メモリ | 30,692 KB |
最終ジャッジ日時 | 2024-07-01 00:46:44 |
合計ジャッジ時間 | 12,965 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 6 ms
6,944 KB |
testcase_05 | AC | 65 ms
6,944 KB |
testcase_06 | AC | 1,054 ms
22,848 KB |
testcase_07 | AC | 1,031 ms
22,772 KB |
testcase_08 | AC | 1,044 ms
22,984 KB |
testcase_09 | AC | 1,059 ms
22,996 KB |
testcase_10 | AC | 8 ms
6,940 KB |
testcase_11 | AC | 50 ms
6,944 KB |
testcase_12 | AC | 769 ms
23,668 KB |
testcase_13 | AC | 746 ms
23,760 KB |
testcase_14 | AC | 125 ms
30,660 KB |
testcase_15 | AC | 247 ms
30,692 KB |
testcase_16 | AC | 442 ms
26,688 KB |
testcase_17 | AC | 1,124 ms
22,976 KB |
testcase_18 | AC | 1,081 ms
22,992 KB |
コンパイルメッセージ
main.cpp: In function 'int main()': main.cpp:294:18: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions] 294 | for(auto [l, r] : vec) { | ^ main.cpp:297:18: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions] 297 | for(auto [l, r] : vec) { | ^
ソースコード
#include <bits/stdc++.h> #define rep(i, n) for(int(i) = 0; (i) < (n); (i)++) #define FOR(i, m, n) for(int(i) = (m); (i) < (n); (i)++) #define ALL(v) (v).begin(), (v).end() #define LLA(v) (v).rbegin(), (v).rend() #define SZ(v) (v).size() #define INT(...) \ int __VA_ARGS__; \ read(__VA_ARGS__) #define LL(...) \ ll __VA_ARGS__; \ read(__VA_ARGS__) #define DOUBLE(...) \ double __VA_ARGS__; \ read(__VA_ARGS__) #define CHAR(...) \ char __VA_ARGS__; \ read(__VA_ARGS__) #define STRING(...) \ string __VA_ARGS__; \ read(__VA_ARGS__) #define VEC(type, name, size) \ vector<type> name(size); \ read(name) using namespace std; using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; using Graph = vector<vector<int>>; template <typename T> struct edge { int to; T cost; edge(int t, T c) : to(t), cost(c) {} }; template <typename T> using WGraph = vector<vector<edge<T>>>; const int INF = 1 << 30; const ll LINF = 1LL << 60; const int MOD = 1e9 + 7; template <class T> inline vector<T> make_vec(size_t a, T val) { return vector<T>(a, val); } template <class... Ts> inline auto make_vec(size_t a, Ts... ts) { return vector<decltype(make_vec(ts...))>(a, make_vec(ts...)); } void read() {} template <class T> inline void read(T &a) { cin >> a; } template <class T, class S> inline void read(pair<T, S> &p) { read(p.first), read(p.second); } template <class T> inline void read(vector<T> &v) { for(auto &a : v) read(a); } template <class Head, class... Tail> inline void read(Head &head, Tail &...tail) { read(head), read(tail...); } template <class T> inline void chmax(T &a, T b) { (a < b ? a = b : a); } template <class T> inline void chmin(T &a, T b) { (a > b ? a = b : a); } // LazySegmentTree template <class Monoid, class Operator = Monoid> class LazySegTree { private: using F = function<Monoid(Monoid, Monoid)>; using G = function<Monoid(Monoid, Operator)>; using H = function<Operator(Operator, Operator)>; size_t n; const F f; const G g; const H h; const Monoid e; const Operator oe; vector<Monoid> node; vector<Operator> lazy; public: LazySegTree(int sz, const F _f, const G _g, const H _h, const Monoid &_e, const Operator &_oe) : f(_f), g(_g), h(_h), e(_e), oe(_oe) { n = 1; while(n < sz) { n <<= 1; } node.resize(2 * n, e); lazy.resize(2 * n, oe); } void set(int k, const Monoid &x) { node[k + n] = x; } void build() { for(int i = n - 1; i > 0; i--) node[i] = f(node[2 * i], node[2 * i + 1]); } // [L,R)区間作用 void update(int L, int R, Operator x) { L += n, R += n; int L0 = L / (L & -L), R0 = R / (R & -R) - 1; thrust(L0); thrust(R0); while(L < R) { if(L & 1) { lazy[L] = h(x, lazy[L]); L++; } if(R & 1) { R--; lazy[R] = h(lazy[R], x); } L >>= 1; R >>= 1; } recalc(L0); recalc(R0); } // [L,R)区間取得 Monoid query(int L, int R) { L += n, R += n; thrust(L / (L & -L)); thrust(R / (R & -R) - 1); Monoid vl = e, vr = e; while(L < R) { if(L & 1) { vl = f(vl, eval(L)); L++; } if(R & 1) { R--; vr = f(eval(R), vr); } L >>= 1; R >>= 1; } return f(vl, vr); } Monoid at(int k) { return query(k, k + 1); } // ノードの評価 inline Monoid eval(int k) { return lazy[k] == oe ? node[k] : g(node[k], lazy[k]); } // 子に伝播 inline void propagate(int k) { if(lazy[k] != oe) { lazy[2 * k] = h(lazy[2 * k], lazy[k]); lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]); node[k] = eval(k); lazy[k] = oe; } } // 上から伝播 inline void thrust(int k) { for(int i = 31 - __builtin_clz(k); i > 0; i--) { if((k >> i) >= 1) propagate(k >> i); } } // 下から再計算 inline void recalc(int k) { while(k > 1) { k >>= 1; node[k] = f(eval(2 * k), eval(2 * k + 1)); } } }; // Range Add and Sum Query // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4955059#1 template <class Monoid, class Operator> struct RASQ : LazySegTree<Monoid, Operator> { using Segtree = LazySegTree<Monoid, Operator>; static Monoid f(Monoid x1, Monoid x2) { return {x1.first + x2.first, x1.second + x2.second}; } static Monoid g(Monoid x, Operator a) { return {x.first + a * x.second, x.second}; } static auto h(Operator a, Operator b) { return a + b; } RASQ(int n, const Monoid &e = {0, 1}, const Operator &oe = 0) : Segtree(n, f, g, h, e, oe) {} }; class HLDecomposition { Graph g; // グラフ(木) vector<int> sz; // もとの木の部分木のサイズ vector<int> par; // もとの木での親 vector<int> hld; // 訪問済み頂点 vector<int> pre; // 行きがけ順 vector<int> head; // 連結成分のうち最も浅い頂点 vector<int> depth; // もとの木での深さ public: HLDecomposition(Graph &g, int root = 0) : g(g), sz(g.size()), par(g.size()), pre(g.size()), head(g.size()), depth(g.size()) { dfs_sz(root, 0, -1); dfs_hld(root, -1, 0); } int dfs_sz(int v, int d, int p) { par[v] = p; if(sz[v] != 0) return sz[v]; sz[v] = 1; depth[v] = d; for(auto nv : g[v]) { if(p == nv) continue; sz[v] += dfs_sz(nv, d + 1, v); } return sz[v]; } void dfs_hld(int v, int p, int h) { pre[v] = hld.size(); hld.push_back(v); head[v] = h; if(par[v] != -1 && g[v].size() == 1) return; int m = 0; int nxt = -1; for(auto nv : g[v]) { if(nv == p) continue; if(sz[nv] > m) { m = sz[nv]; nxt = nv; } } dfs_hld(nxt, v, h); for(auto nv : g[v]) { if(p == nv) continue; if(nv != nxt) dfs_hld(nv, v, nv); } } vector<pii> query(int u, int v) { vector<pair<int, int>> ret; while(head[u] != head[v]) { if(depth[head[u]] <= depth[head[v]]) { ret.push_back({pre[head[v]], pre[v]}); v = par[head[v]]; } else { ret.push_back({pre[head[u]], pre[u]}); u = par[head[u]]; } } ret.push_back({min(pre[u], pre[v]), max(pre[u], pre[v])}); return ret; } int lca(int u, int v) { for(;; v = par[head[v]]) { if(pre[u] > pre[v]) swap(u, v); if(head[u] == head[v]) return u; } } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); INT(n); Graph g(n); rep(i, n - 1) { INT(u, v); u--, v--; g[u].push_back(v); g[v].push_back(u); } HLDecomposition tree(g); RASQ<pll, ll> segtree(n); rep(i, n) segtree.set(i, {1, 1}); segtree.build(); INT(q); ll res = 0; rep(i, q) { INT(a, b); a--, b--; auto vec = tree.query(a, b); ll ans = 0; for(auto [l, r] : vec) { ans += segtree.query(l, r + 1).first; } for(auto [l, r] : vec) { segtree.update(l, r + 1, 1); } res += ans; } cout << res << endl; }