結果
問題 | No.399 動的な領主 |
ユーザー | autumn-eel |
提出日時 | 2018-05-04 13:48:49 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 429 ms / 2,000 ms |
コード長 | 2,666 bytes |
コンパイル時間 | 1,779 ms |
コンパイル使用メモリ | 175,348 KB |
実行使用メモリ | 24,704 KB |
最終ジャッジ日時 | 2024-06-28 01:02:11 |
合計ジャッジ時間 | 6,350 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 4 ms
8,192 KB |
testcase_01 | AC | 5 ms
8,576 KB |
testcase_02 | AC | 5 ms
8,320 KB |
testcase_03 | AC | 4 ms
8,320 KB |
testcase_04 | AC | 6 ms
8,320 KB |
testcase_05 | AC | 30 ms
9,088 KB |
testcase_06 | AC | 403 ms
15,488 KB |
testcase_07 | AC | 393 ms
15,360 KB |
testcase_08 | AC | 391 ms
15,616 KB |
testcase_09 | AC | 385 ms
15,616 KB |
testcase_10 | AC | 7 ms
8,320 KB |
testcase_11 | AC | 24 ms
9,344 KB |
testcase_12 | AC | 287 ms
15,872 KB |
testcase_13 | AC | 291 ms
16,128 KB |
testcase_14 | AC | 98 ms
24,704 KB |
testcase_15 | AC | 136 ms
23,552 KB |
testcase_16 | AC | 190 ms
19,328 KB |
testcase_17 | AC | 429 ms
15,360 KB |
testcase_18 | AC | 407 ms
15,616 KB |
ソースコード
#include <bits/stdc++.h> #define rep(i,n)for(int i=0;i<(n);i++) using namespace std; typedef long long ll; #ifndef MAX #define MAX 400000 #endif //Range Add Query+Range Sum Query template<class T> class RAQ_RSQ { public: int n; T dat[MAX], lazy[MAX], ZERO; void init(int n_) { ZERO = T(); n = 1; while (n < n_)n <<= 1; for (int i = 0; i < 2 * n - 1; i++) { dat[i] = lazy[i] = ZERO; } } inline void push(int k, int s) { dat[k] = dat[k] + lazy[k] * s; if (k < n - 1) { lazy[k * 2 + 1] = lazy[k * 2 + 1] + lazy[k]; lazy[k * 2 + 2] = lazy[k * 2 + 2] + lazy[k]; } lazy[k] = ZERO; } inline void update_node(int k) { dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2]; } inline void update(int a, int b, T x, int k, int l, int r) { push(k, r - l); if (r <= a || b <= l)return; if (a <= l&&r <= b) { lazy[k] = lazy[k] + x; push(k, r - l); return; } update(a, b, x, k * 2 + 1, l, (l + r) / 2); update(a, b, x, k * 2 + 2, (l + r) / 2, r); update_node(k); } inline T query(int a, int b, int k, int l, int r) { push(k, r - l); if (r <= a || b <= l)return ZERO; if (a <= l&&r <= b)return dat[k]; T lb = query(a, b, k * 2 + 1, l, (l + r) / 2); T rb = query(a, b, k * 2 + 2, (l + r) / 2, r); update_node(k); return lb + rb; } inline void update(int a, int b, T x) { update(a, b, x, 0, 0, n); } inline void update(int a, T x) { update(a, a + 1, x); } inline T query(int a, int b) { return query(a, b, 0, 0, n); } inline T query(int a) { return query(a, a + 1); } }; RAQ_RSQ<int>seg; vector<int>E[200000]; int par[200000],d[200000],sub[200000]; int chain[200000],vid[200000]; int node_num; void dfs(int v,int p,int dep){ par[v]=p;d[v]=dep; sub[v]=1; for(int u:E[v]){ if(u==p)continue; dfs(u,v,dep+1); sub[v]+=sub[u]; } } void hld(int v,int k){ chain[v]=k; vid[v]=node_num++; int Max=0,id=-1; for(int u:E[v]){ if(u==par[v])continue; if(Max<sub[u]){ Max=sub[u]; id=u; } } if(id==-1)return; hld(id,chain[v]); for(int u:E[v]){ if(u==id||u==par[v])continue; hld(u,u); } } void update(int u,int v){ while(1){ if(d[chain[u]]>d[chain[v]])swap(u,v); if(chain[u]==chain[v]){ seg.update(min(vid[u],vid[v]),max(vid[u],vid[v])+1,1); break; } else{ seg.update(vid[chain[v]],vid[v]+1,1); v=par[chain[v]]; } } } int main(){ int n;scanf("%d",&n); rep(i,n-1){ int u,v;scanf("%d%d",&u,&v);u--;v--; E[u].push_back(v);E[v].push_back(u); } dfs(0,-1,0); hld(0,0); seg.init(n); int q;scanf("%d",&q); rep(i,q){ int a,b;scanf("%d%d",&a,&b);a--;b--; update(a,b); } ll ans=0; rep(i,n){ ll a=seg.query(vid[i]); ans+=(a+1)*a/2; } cout<<ans<<endl; }