QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#462567 | #3226. Distance Sum | propane | TL | 2799ms | 114108kb | C++20 | 10.3kb | 2024-07-03 21:00:18 | 2024-07-03 21:00:19 |
Judging History
answer
#include<iostream>
#include<cstring>
#include<vector>
#include<numeric>
#include<functional>
#include<algorithm>
using namespace std;
using LL = long long;
// d(u, v) = dep(u) + dep(v) - 2 dep(anc)
// 维护一个点的子树内已经有的深度和 减去两倍的本身深度 以及点的个数
// 因为会重复,所以需要类似点分树维护子树的贡献,减去避免重复计数
struct Info{
LL dep = 0, len = 0, cnt = 0, sum = 0;
};
struct Tag{
LL cnt = 0, sum = 0;
};
Info operator+(const Info &a, const Info &b){
return {a.dep + b.dep, a.len + b.len, a.cnt + b.cnt, a.sum + b.sum};
}
void apply(Info &x, Tag &a, Tag f){
x.cnt += x.len * f.cnt;
x.sum += x.len * f.sum - 2 * x.dep * f.cnt;
a.cnt += f.cnt;
a.sum += f.sum;
}
template<class Info, class Tag>
struct LazySegmentTree{
int n;
vector<Info> info;
vector<Tag> tag;
LazySegmentTree() {}
LazySegmentTree(int n, Info _init = Info()){
init(vector<Info>(n, _init));
}
LazySegmentTree(const vector<Info> &_init){
init(_init);
}
void init(const vector<Info> &_init){
n = (int)_init.size();
info.assign((n << 2) + 1, Info());
tag.assign((n << 2) + 1, Tag());
function<void(int, int, int)> build = [&](int p, int l, int r){
if (l == r){
info[p] = _init[l - 1];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m + 1, r);
pull(p);
};
build(1, 1, n);
}
void pull(int p){
info[p] = info[2 * p] + info[2 * p + 1];
}
void apply(int p, const Tag &v){
::apply(info[p], tag[p], v);
}
void push(int p){
apply(2 * p, tag[p]);
apply(2 * p + 1, tag[p]);
tag[p] = Tag();
}
void modify(int p, int l, int r, int x, const Info &v){
if (l == r){
info[p] = v;
return;
}
int m = (l + r) / 2;
push(p);
if (x <= m){
modify(2 * p, l, m, x, v);
}
else{
modify(2 * p + 1, m + 1, r, x, v);
}
pull(p);
}
void modify(int p, const Info &v){
modify(1, 1, n, p, v);
}
Info query(int p, int l, int r, int x, int y){
if (l > y || r < x){
return Info();
}
if (l >= x && r <= y){
return info[p];
}
int m = (l + r) / 2;
push(p);
return query(2 * p, l, m, x, y) + query(2 * p + 1, m + 1, r, x, y);
}
Info query(int l, int r){
return query(1, 1, n, l, r);
}
void modify(int p, int l, int r, int x, int y, const Tag &v){
if (l > y || r < x){
return;
}
if (l >= x && r <= y){
apply(p, v);
return;
}
int m = (l + r) / 2;
push(p);
modify(2 * p, l, m, x, y, v);
modify(2 * p + 1, m + 1, r, x, y, v);
pull(p);
}
void modify(int l, int r, const Tag &v){
return modify(1, 1, n, l, r, v);
}
};
// 1_based HLD
struct Edge{
int to;
int w;
operator int() const { return to; }
};
struct HLD{
int n;
vector<int> sz, top, dep, fa, in, out, seq;
vector<LL> dis;
vector<vector<Edge> > g;
int ts;
HLD(const vector<vector<Edge> > &g, int root = 1) : n(int(g.size()) - 1), g(g) {
ts = 0;
sz.resize(n + 1);
top.resize(n + 1);
dep.resize(n + 1);
fa.resize(n + 1);
in.resize(n + 1);
out.resize(n + 1);
seq.resize(n + 1);
dis.resize(n + 1);
dep[root] = 1;
top[root] = root;
dfs_sz(root);
dfs_hld(root);
}
void dfs_sz(int u){
if (fa[u]){
for(auto it = g[u].begin(); it != g[u].end(); it++){
if (*it == fa[u]){
g[u].erase(it);
break;
}
}
}
sz[u] = 1;
for(auto &j : g[u]){
fa[j] = u;
dep[j] = dep[u] + 1;
dis[j] = dis[u] + j.w;
dfs_sz(j);
sz[u] += sz[j];
if (sz[j] > sz[g[u][0]])
swap(j, g[u][0]);
}
}
void dfs_hld(int u){
in[u] = ++ts;
seq[in[u]] = u;
for (auto j : g[u]){
top[j] = (j == g[u][0] ? top[u] : j);
dfs_hld(j);
}
out[u] = ts;
}
int lca(int u, int v){
while (top[u] != top[v]){
if (dep[top[u]] > dep[top[v]]){
u = fa[top[u]];
}
else{
v = fa[top[v]];
}
}
return dep[u] < dep[v] ? u : v;
}
int dist(int u, int v){
return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}
bool in_subtree(int u, int v){
return in[v] <= in[u] && in[u] <= out[v];
}
int jump(int u, int k) {
if (dep[u] < k){
return -1;
}
int d = dep[u] - k;
while (dep[top[u]] > d){
u = fa[top[u]];
}
return seq[in[u] - dep[u] + d];
}
int rooted_lca(int a, int b, int c){
return lca(a, b) ^ lca(b, c) ^ lca(c, a);
}
template<typename Q>
void modify_path(int u, int v, const Q &q, bool edge = false){
while(top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u, v);
q(in[top[u]], in[u]);
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
q(in[u] + edge, in[v]);
}
template<typename Q>
void modify_subtree(int u, const Q &q){
q(in[u], out[u]);
}
template<typename T, typename Q>
T query_path(int u, int v, const Q &q, bool edge = false){
T ret = T();
while(top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u, v);
ret = q(in[top[u]], in[u]) + ret;
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
return q(in[u] + edge, in[v]) + ret;
}
template<typename T, typename Q>
T query_subtree(int u, const Q &q){
return q(in[u], out[u]);
}
template<typename T, typename Q, typename F>
T query_path_noncommutative(int u, int v, const Q &q, const F &f, bool edge = false){
T left = T(), right = T();
while(top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u, v), swap(left, right);
left = q(in[top[u]], in[u]) + left;
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u, v), swap(left, right);
return f(left, q(in[u] + edge, in[v]) + right);
}
pair<vector<int>, vector<pair<int, int> > > compress(vector<int> v){
auto cmp = [&](int a, int b) { return in[a] < in[b]; };
sort(v.begin(), v.end(), cmp);
v.erase(unique(v.begin(), v.end()), v.end());
const int k = (int)v.size();
for(int i = 0; i + 1 < k; i++){
v.push_back(lca(v[i], v[i + 1]));
}
sort(v.begin(), v.end(), cmp);
v.erase(unique(v.begin(), v.end()), v.end());
vector<pair<int, int> > edges;
vector<int> stk;
for(auto x : v){
while(!stk.empty() && out[stk.back()] < in[x]){
stk.pop_back();
}
if (!stk.empty()){
edges.push_back({stk.back(), x});
}
stk.push_back(x);
}
return {v, edges};
}
};
int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
vector<vector<Edge> > g(n + 1);
for(int i = 2; i <= n; i++){
int p, w;
cin >> p >> w;
g[p].push_back({i, w});
}
HLD hld(g);
vector<Info> init1(n), init2(n);
for(int i = 1; i <= n; i++){
int x = hld.seq[i];
init1[i - 1] = {hld.dis[x], 1, 0, 0};
}
for(int i = 2; i <= n; i++){
int x = hld.fa[hld.seq[i]];
init2[i - 1] = {hld.dis[x], 1, 0, 0};
}
LazySegmentTree<Info, Tag> seg1(init1), seg2(init2);
auto change = [&](int x){
{
auto f = [&](int l, int r){
seg1.modify(l, r, {1, hld.dis[x]});
};
hld.modify_path(1, x, f);
}
if (x != 1){
auto f = [&](int l, int r){
seg2.modify(l, r, {1, hld.dis[x]});
};
int t = hld.jump(x, hld.dep[x] - hld.dep[1] - 1);
hld.modify_path(t, x, f);
}
};
auto get = [&](int x){
Info res1 = Info(), res2 = Info();
{
auto q = [&](int l, int r){
return seg1.query(l, r);
};
res1 = hld.query_path<Info>(1, x, q);
}
{
auto q = [&](int l, int r){
return seg2.query(l, r);
};
res2 = hld.query_path<Info>(1, x, q);
}
LL cnt = res1.cnt - res2.cnt;
LL sum = res1.sum - res2.sum;
return sum + cnt * hld.dis[x];
};
cout << 0 << '\n';
int last = 1;
change(1);
for(int i = 2; i <= n; i++){
change(i);
int anc = hld.lca(last, i);
int len = hld.dep[i] + hld.dep[last] - 2 * hld.dep[anc];
auto get_pos = [&](int t){
int x = -1;
if (t <= hld.dep[last] - hld.dep[anc]){
x = hld.jump(last, t);
}
else{
x = hld.jump(i, len - t);
}
return x;
};
auto f = [&](int t){
return get(get_pos(t));
};
int l = 0, r = len;
while(l < r){
int m1 = l + (r - l) / 3;
int m2 = r - (r - l) / 3;
if (f(m1) >= f(m2)) l = m1 + 1;
else r = m2 - 1;
}
last = get_pos(r);
cout << get(last) << '\n';
}
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3520kb
input:
10 5 1 2 1 1 1 4 1 2 1 5 1 2 1 2 1 5 1
output:
0 3 4 6 6 8 9 11 12 14
result:
ok 10 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 3552kb
input:
10 5 1 10 1 5 1 3 1 5 1 5 1 1 1 3 1 1 1
output:
0 4 4 6 6 7 8 12 14 16
result:
ok 10 lines
Test #3:
score: 0
Accepted
time: 0ms
memory: 3604kb
input:
10 4 1 7 1 9 1 3 1 7 1 1 1 7 1 6 1 3 1
output:
0 5 6 9 11 12 12 13 15 17
result:
ok 10 lines
Test #4:
score: 0
Accepted
time: 0ms
memory: 3548kb
input:
10 1 1 9 1 9 1 6 1 9 1 3 1 10 1 1 1 3 1
output:
0 1 3 5 7 8 10 13 13 15
result:
ok 10 lines
Test #5:
score: 0
Accepted
time: 0ms
memory: 3624kb
input:
10 6 1 6 1 3 1 3 1 1 1 1 1 9 1 3 1 1 1
output:
0 2 3 5 6 7 9 12 13 16
result:
ok 10 lines
Test #6:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
10 8 1 10 1 6 1 3 1 1 1 1 1 4 1 5 1 4 1
output:
0 4 6 6 9 10 13 14 18 19
result:
ok 10 lines
Test #7:
score: 0
Accepted
time: 0ms
memory: 3592kb
input:
10 5 1 8 1 9 1 1 1 1 1 5 1 5 1 1 1 1 1
output:
0 2 4 7 7 9 10 11 13 15
result:
ok 10 lines
Test #8:
score: 0
Accepted
time: 0ms
memory: 3492kb
input:
10 5 1 5 1 8 1 4 1 5 1 4 1 1 1 2 1 7 1
output:
0 4 5 6 6 7 9 11 13 16
result:
ok 10 lines
Test #9:
score: 0
Accepted
time: 0ms
memory: 3628kb
input:
10 4 1 1 1 3 1 3 1 5 1 6 1 6 1 8 1 4 1
output:
0 3 3 4 5 7 10 13 16 19
result:
ok 10 lines
Test #10:
score: 0
Accepted
time: 0ms
memory: 3620kb
input:
10 8 1 10 1 8 1 4 1 9 1 10 1 1 1 8 1 8 1
output:
0 2 4 5 7 9 11 11 12 13
result:
ok 10 lines
Test #11:
score: 0
Accepted
time: 2799ms
memory: 114108kb
input:
200000 109891 65231 171839 5776 32431 29819 62570 71905 153470 68881 188361 76298 151469 77636 75162 130242 95864 47113 191182 742 121927 111781 18165 51034 158645 36001 193496 189958 143195 29723 140274 86466 117583 23287 184465 144332 35935 128306 192514 116854 27679 197718 138926 123165 46773 177...
output:
0 2128476 3615067 4333135 5793589 7104606 7876598 9621410 10959705 12443304 12989537 15017823 15660417 16551255 18007974 18487621 20027188 21203385 22454974 22931660 23796204 25173856 26195907 27604778 28662852 29446260 30856590 32645490 33338651 34979442 36020161 37417274 38263592 39224218 40460394...
result:
ok 200000 lines
Test #12:
score: -100
Time Limit Exceeded
input:
200000 196697 155143 178488 159177 49016 18473 171950 94863 69271 100194 160889 20733 40420 19766 191138 127108 142060 2610 194472 41608 6942 105158 61037 3025 150904 197834 58272 30296 5859 116513 104509 1986 48140 173435 131223 123177 175812 40180 28608 98965 157005 67994 127784 114441 17436 68620...
output:
0 11320917384 11874614449 15772614655 18523775058 21957641652 30009559722 31970095838 35324661901 38253652284 48493111245 51933582990 58121449414 67628507769 73905238960 83828871781 83828871781 86351127383 86906418351 88386492876 89035727731 94945127602 103238157194 103565667357 106031510890 1148471...