제출 #1248586

#제출 시각아이디문제언어결과실행 시간메모리
1248586qwerasdfzxcl트리 (IOI24_tree)C++20
70 / 100
124 ms64996 KiB
#include "tree.h" #include <bits/stdc++.h> using namespace std; using ll = long long; constexpr int SZ = 1001000; int n; vector<int> adj[200200], buf[SZ+2]; ll a[200200], suf1[SZ+2], suf2[SZ+2], sum; struct DSU{ int path[200200], rt[200200]; ll sum[200200]; void init(int n){ for (int i=1;i<=n;i++) path[i] = i; } int find(int s){ if (s==path[s]) return s; return path[s] = find(path[s]); } void toggle(int x, int t, ll v){ assert(!rt[x]); rt[x] = t; sum[x] = v; } void push(int x, int t){ x = find(x); suf1[min(sum[x], (ll)SZ)] += sum[x] * (rt[x] - t); suf2[min(sum[x], (ll)SZ)] += rt[x] - t; rt[x] = t; } void merge(int x, int y, int t){ x = find(x); y = find(y); if (!rt[x] || !rt[y]) return; push(x, t); push(y, t); if (x==y) return; path[x] = y; sum[y] += sum[x]; } }dsu; void init(std::vector<int> P, std::vector<int> W) { n = P.size(); for (int i=1;i<n;i++) adj[P[i]+1].push_back(i+1); for (int i=0;i<n;i++) a[i+1] = W[i]; for (int i=1;i<=n;i++) if (adj[i].empty()) sum += a[i]; dsu.init(n); for (int i=1;i<=n;i++) if (!adj[i].empty()) buf[a[i]].push_back(i); for (int t=SZ-1;t>=1;t--){ for (auto &x:buf[t]){ dsu.toggle(x, t, max((int)adj[x].size() - 1, 0)); dsu.merge(x, P[x-1]+1, t); for (auto &y:adj[x]) dsu.merge(x, y, t); } } dsu.push(1, 0); for (int i=SZ;i>=0;i--) suf1[i] += suf1[i+1], suf2[i] += suf2[i+1]; } long long query(int L, int R) { return sum * L + suf1[(R-L) / L + 1] * L - suf2[(R-L) / L + 1] * (R-L); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...