結果
問題 | No.399 動的な領主 |
ユーザー | manjuuu_onsen |
提出日時 | 2024-02-26 01:32:07 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 520 ms / 2,000 ms |
コード長 | 3,691 bytes |
コンパイル時間 | 2,192 ms |
コンパイル使用メモリ | 186,592 KB |
実行使用メモリ | 23,940 KB |
最終ジャッジ日時 | 2024-09-29 11:31:49 |
合計ジャッジ時間 | 8,418 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 3 ms
5,248 KB |
testcase_05 | AC | 35 ms
5,248 KB |
testcase_06 | AC | 506 ms
17,752 KB |
testcase_07 | AC | 492 ms
17,784 KB |
testcase_08 | AC | 488 ms
17,864 KB |
testcase_09 | AC | 497 ms
17,828 KB |
testcase_10 | AC | 5 ms
6,816 KB |
testcase_11 | AC | 29 ms
6,816 KB |
testcase_12 | AC | 383 ms
18,224 KB |
testcase_13 | AC | 376 ms
18,292 KB |
testcase_14 | AC | 149 ms
23,928 KB |
testcase_15 | AC | 188 ms
23,940 KB |
testcase_16 | AC | 271 ms
20,892 KB |
testcase_17 | AC | 520 ms
17,800 KB |
testcase_18 | AC | 500 ms
18,000 KB |
コンパイルメッセージ
main.cpp: In function 'int main()': main.cpp:162:26: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions] 162 | for(auto [l,r]:s) { | ^
ソースコード
#include<bits/stdc++.h> using namespace std; using ll = long long; using P = pair<int,int>; /* ☆HLDの使い方☆ まずbuildする ①頂点に値がある場合: - 代入はseg[hld.in[v]] = a[v] - パスクエリはfor_each_vertex(u,v) - 部分木クエリは hld.in[v] ~ hld.out[v]で ②辺に値がある場合: - 代入(aとbの間の辺に重みw)は (par[a] == b ? seg[hld.in[a]] = w : seg[hld.in[b]] = w) - パスクエリはfor_each_edge(u, v) 非可換だと壊れると思う */ struct HLD { int n; vector<int> par,in,out,head,inv,sub; vector<vector<int>> g; HLD(){}; HLD(int n) { g = vector<vector<int>>(n); sub = par = in = out = head = inv = vector<int>(n); } void add_edge(int u, int v) { g[u].push_back(v); g[v].push_back(u); } int dfs_hld(int c, int p) { sub[c] = 1; if(p != -1) g[c].erase(find(g[c].begin(), g[c].end(), p)); for(auto &d :g[c]) { par[d] = c; sub[c] += dfs_hld(d, c); if(sub[d] > sub[g[c][0]]) swap(d, g[c][0]); } return sub[c]; } void dfs2(int c, int &i) { in[c] = i++; inv[in[c]] = c; for(auto &d : g[c]) { head[d] = (g[c][0] == d ? head[c] : d); dfs2(d,i); } out[c] = i; } void build(int r=0) { dfs_hld(0,-1); int cnt = 0; dfs2(0,cnt); } int lca(int u, int v) { while(1) { if(in[u] > in[v]) swap(u,v); if(head[u] == head[v]) return u; v = par[head[v]]; } } vector<pair<int,int>> for_each_vertex(int u, int v) { //seg[in[u]] に代入 vector<pair<int,int>> path; while(1) { if(in[u] > in[v]) swap(u,v); if(head[u] != head[v]) { path.push_back({in[head[v]], in[v] + 1}); v = par[head[v]]; }else { path.push_back({in[u],in[v]+1}); return path; } } } vector<pair<int,int>> for_each_edge(int u, int v) { //子に辺の情報を代入 vector<P> path; while(1) { if(in[u] > in[v]) swap(u,v); if(head[u] != head[v]) { path.push_back({in[head[v]], in[v] + 1}); v = par[head[v]]; } else { path.push_back({in[u] + 1, in[v] + 1}); return path; } } } }; template<typename T> struct fenwick_tree { int n; vector<T> bit; fenwick_tree(){}; fenwick_tree(int n):n(n), bit(n+1,0){} void add(int i, T x) { i++; for(int idx=i; idx<=n; idx += (idx & (-idx))) bit[idx] += x; } T sum(int i) { T s(0); for(int idx=i; idx>0; idx-= (idx & (-idx)) ) s += bit[idx]; return s; } T sum(int l, int r) {return sum(r) - sum(l);} int lower_bound(T w) { if(w <= 0) return 0; int x=0, r=1; while(r < n) r = r<<1; for(int len = r; len > 0; len = len>>1) { if(x + len < n && bit[x+len] < w) { w -= bit[x + len]; x += len; } } return x+1; } }; #include<atcoder/lazysegtree> using namespace atcoder; /* ☆atcoder::lazy_segtreeの使い方☆ <typename S, S (*op)(S, S), S (*e)(), typename F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()> lazy_segtree 作用素の合成composition(F f, F g) は f∘gとなる(つまりfが後から来たもの) ↓↓↓↓↓↓区間和・区間加算 */ struct S { ll x; int l; }; S op(S a, S b){return {a.x + b.x, a.l + b.l};} S e(){return {0,0};} using F = ll; S mapping(F f, S x) {return {x.x + x.l*f,x.l};} F composition(F f, F g){return f + g;} F id(){return 0;} int main() { int N; cin>>N; HLD hl(N); for(int i=0; i<N-1; i++) { int u,v;cin>>u>>v; u--,v--; hl.add_edge(u,v); } hl.build(); lazy_segtree<S,op,e,F,mapping,composition,id> seg(N); for(int i=0; i<N; i++) seg.set(i, {0,1}); int Q; cin>>Q; ll ans = 0; while(Q--) { int u,v;cin>>u>>v; u--,v--; auto s = hl.for_each_vertex(u,v); for(auto [l,r]:s) { ans += seg.prod(l,r).x + (r - l); seg.apply(l,r,1); } } cout << ans << endl; }