Submission #1320420

#TimeUsernameProblemLanguageResultExecution timeMemory
1320420fact493Tree (IOI24_tree)C++20
0 / 100
93 ms68116 KiB
//#define _GLIBCXX_DEBUG #include<bits/stdc++.h> using namespace std; using ll = long long; using vl = vector<ll>; using vvl = vector<vl>; using vi = vector<int>; using vvi = vector<vector<int>>; typedef pair<ll, ll> P; using vs = vector<string>; using vvs = vector<vs>; using vp = vector<P>; using vvp = vector<vp>; using vb = vector<bool>; using vvb = vector<vb>; #define rep(i, n) for (ll i = 0; i < (ll)(n); i++) #define all(a) (a).begin(), (a).end() #define lb(v, k) (lower_bound(all(v), (k)) - v.begin()) #define ub(v, k) (upper_bound(all(v), (k)) - v.begin()) #define fi first #define se second #define pb push_back #define double long double template <typename T> bool chmax(T &a, const T &b){ if(a < b){ a = b; return true; } return false; } template <typename T> bool chmin(T &a, const T &b){ if(a > b){ a = b; return true; } return false; } ll mod = 998244353; ll inf = 999999999999999999LL; struct union_find{ int n; vl root; vl siz; vvl S; ll ans = 0; void init(int N){ n = N; root.assign(N, -1); siz.assign(N, 1); S.assign(N, vl(2)); } vl st; int leader(int p){ while(root[p] != -1){ st.pb(p); p = root[p]; } for(auto x : st){ root[x] = p; } st.clear(); return p; } bool same(int p, int q){ return (leader(p) == leader(q)); } int merge(int p, int q){ p = leader(p), q = leader(q); if(p != q){ if(siz[p] < siz[q]){ swap(p, q); } S[p][0] += S[q][0]; siz[p] += siz[q]; root[q] = p; } return p; } }; vi root; vl W; ll N = 0; ll ans = 0; vl sm1, sm2; void init(std::vector<int> PP, std::vector<int> WW){ N = PP.size(); root.assign(N, 0); W.assign(N, 0); rep(i, N){ root[i] = PP[i]; W[i] = WW[i]; } vvi X(1000001); rep(i, N){ X[W[i]].pb(i); } vvi G(N); rep(i, N){ if(root[i] != -1){ G[root[i]].pb(i); G[i].pb(root[i]); } } vl now(N); vl leaf(N); union_find D; D.init(N);// leafcnt last vector<ll> que(N + 1); for(int t = 1000000;t >= 0;t--){ for(auto p : X[t]){ now[p] = 1; D.S[p][0] = 1; D.S[p][1] = t; leaf[p] = 1; for(auto q : G[p]){ if(now[q] == 1){ int a, b; a = p, b = q; if(root[a] == b){ swap(a, b); } int c, d; c = D.leader(a), d = D.leader(b); ans += D.S[c][0] * (D.S[c][1] - t); ans += D.S[d][0] * (D.S[d][1] - t); que[D.S[c][0]] += D.S[c][1] - t; que[D.S[d][0]] += D.S[d][1] - t; D.S[c][0] -= leaf[a]; leaf[a] = 0; int r = D.merge(c, d); D.S[r][1] = t; //cout << p << ' ' << q << ' ' << D.S[r][0] << ' ' << D.S[r][1] << endl; } } } } int p = D.leader(0); ans += D.S[p][0] * (D.S[p][1]); que[D.S[p][0]] += D.S[p][1]; sm1.assign(N + 1, 0);//kl sum sm2.assign(N + 1, 0);//R sum sm1[N] = N * que[N]; sm2[N] = que[N]; for(int i = N - 1;i >= 0;i--){ sm1[i] = i * que[i]; sm1[i] += sm1[i + 1]; sm2[i] = que[i]; sm2[i] += que[i + 1]; } return ; } long long query(int L, int R){ ll p = R / L; p++; chmin(p, N); return sm1[p] * L - sm2[p] * R + ans * 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...