結果
問題 | No.399 動的な領主 |
ユーザー | houren |
提出日時 | 2023-12-07 15:31:42 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 622 ms / 2,000 ms |
コード長 | 4,322 bytes |
コンパイル時間 | 2,855 ms |
コンパイル使用メモリ | 223,228 KB |
実行使用メモリ | 33,600 KB |
最終ジャッジ日時 | 2024-09-27 02:11:45 |
合計ジャッジ時間 | 8,991 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
5,248 KB |
testcase_01 | AC | 0 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 3 ms
5,376 KB |
testcase_05 | AC | 38 ms
5,888 KB |
testcase_06 | AC | 594 ms
28,360 KB |
testcase_07 | AC | 566 ms
28,544 KB |
testcase_08 | AC | 569 ms
28,480 KB |
testcase_09 | AC | 564 ms
28,544 KB |
testcase_10 | AC | 6 ms
5,376 KB |
testcase_11 | AC | 29 ms
6,016 KB |
testcase_12 | AC | 421 ms
28,032 KB |
testcase_13 | AC | 404 ms
27,776 KB |
testcase_14 | AC | 137 ms
33,600 KB |
testcase_15 | AC | 173 ms
33,536 KB |
testcase_16 | AC | 278 ms
31,096 KB |
testcase_17 | AC | 622 ms
28,288 KB |
testcase_18 | AC | 586 ms
28,416 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; #include <atcoder/lazysegtree> using namespace atcoder; using ll = long long; using P = pair<ll,ll>; #define fix(x) fixed << setprecision(x) #define asc(x) x, vector<x>, greater<x> #define rep(i, n) for(ll i = 0; i < n; ++i) #define all(x) (x).begin(),(x).end() template<class T>bool chmin(T&a, const T&b){if(a>b){a=b;return 1;}return 0;} template<class T>bool chmax(T&a, const T&b){if(a<b){a=b;return 1;}return 0;} constexpr ll INFLL = (1LL << 62), MOD = 998244353; constexpr int INF = (1 << 30); // op(S,S): 交換律を満たす二項演算(結合律は未実装) // Edge: 重みはSであること // V: Sの配列型 vector<S>を引数に与えると生成されるデータ構造であること // F: S->Sの関数 // R(V v, int l, int r, F x): 区間[l,r)操作クエリ // Q(V v, int l, int r): 区間[l,r)演算処理クエリ 返り値の型はSであること template<class S, S (*op)(S, S), S (*e)(), class Edge, class V, class F, void (*R)(V&, int, int, F), S (*Q)(V&, int, int)> struct HLD{ int n, root; vector<vector<Edge>> g; vector<S> data_; V data; vector<int> st_size, label, par, top; HLD(){} HLD(const vector<vector<Edge>>& _g, int r = 0) : n(_g.size()), g(_g), root(r), data_(n), st_size(n,1), label(n), par(n,-1), top(n){ par[root] = -1; dfs_size(root); int num = 0; dfs_hld(root, num, root); data = V(data_); } void dfs_size(int now){ for(Edge& edge:g[now]){ if(par[now]==edge.to) continue; par[edge.to] = now; dfs_size(edge.to); st_size[now] += st_size[edge.to]; if(st_size[g[now][0].to] < st_size[edge.to]) swap(g[now][0], edge); } } void dfs_hld(int now, int& num, int t){ label[now] = num, top[now] = t; for(Edge& edge:g[now]){ if(edge.to==par[now]) continue; data_[num++] = edge.w; dfs_hld(edge.to, num, (edge==g[now][0] ? t : edge.to)); } } // {op(u,...,v), lca(u,v)} pair<S, int> prod(int u, int v){ S res = e(); while(top[u]!=top[v]){ if(label[u]>label[v]){ res = op(res, Q(data, label[top[u]] - (top[u]!=root), label[u])); u = (top[u]!=root ? par[top[u]] : top[u]); }else{ res = op(res, Q(data, label[top[v]] - (top[v]!=root), label[v])); v = (top[v]!=root ? par[top[v]] : top[v]); } } res = op(res, (label[u]<label[v] ? Q(data, label[u], label[v]) : Q(data, label[v], label[u]))); return {res, (label[u]<label[v] ? u : v)}; } // 列操作クエリ int apply(int u, int v, F x){ if(label[u]<label[v]) swap(u,v); while(top[u]!=top[v]){ R(data, label[top[u]] - (top[u]!=root), label[u], x); u = (top[u]!=root ? par[top[u]] : top[u]); if(label[u]<label[v]) swap(u,v); } R(data, label[v], label[u], x); return v; } }; struct S{ ll val, siz; S(ll a, ll b){ val = a, siz = b; } S(){ val = 0, siz = 1; } }; S op(S a, S b){ return {a.val+b.val, a.siz+b.siz}; } S e(){ return S(0,1); } S mapping(ll x, S a){ return {a.val+a.siz*x, a.siz}; } ll composition(ll x, ll y){ return x+y; } ll id(){ return 0; } using SEG = lazy_segtree<S,op,e,ll,mapping,composition,id>; struct Edge{ int to; S w; bool operator==(Edge& edge){ return to==edge.to; } }; void R(SEG& seg, int l, int r, ll x){ seg.apply(l,r,x); } S Q(SEG& seg, int l, int r){ return seg.prod(l,r); } int main(){ cin.tie(nullptr); ios::sync_with_stdio(false); int n; cin >> n; vector<vector<Edge>> g(n); rep(i,n-1){ int u,v; cin >> u >> v; u--; v--; g[u].push_back({v,S(0,1)}); g[v].push_back({u,S(0,1)}); } HLD<S,op,e,Edge,SEG,ll,R,Q> hld(g); int q; cin >> q; ll ans = 0, t = 0; while(q--){ int u,v; cin >> u >> v; u--; v--; int r = hld.apply(u,v,1); if(r) hld.apply(r,hld.par[r],1); else t++; ans += hld.prod(u,v).first.val; if(r) ans += hld.prod(r,hld.par[r]).first.val; else ans += t; } cout << ans << '\n'; return 0; }