QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#204914 | #7563. Fun on Tree | ucup-team1209# | WA | 4ms | 34204kb | C++20 | 6.9kb | 2023-10-07 14:21:49 | 2023-10-07 14:21:50 |
Judging History
answer
#include<bits/stdc++.h>
using std::cin;
using std::cout;
const int N = 200005;
using ll = long long;
struct bit {
ll a[N];
void add(int l, int r, int v) {
for(int i = l;i < N;i += i & -i) a[i] += v;
for(int i = r + 1;i < N;i += i & -i) a[i] -= v;
}
ll qry(int p) {
ll sum = 0;
for(;p;p &= p - 1) {
sum += a[p];
}
return sum;
}
} tag;
using pr = std::pair<ll, int>;
struct sgt {
std::vector<pr> sgt;
std::vector<int> add;
int n;
void update(int x) {
sgt[x] = std::max(sgt[x << 1], sgt[x << 1 | 1]);
}
void put(int x, ll v) {
add[x] += v;
sgt[x].first += v;
}
void down(int x) {
put(x << 1, add[x]);
put(x << 1 | 1, add[x]);
add[x] = 0;
}
void build(int cur, int l, int r, auto & v) {
if(l == r) {
sgt[cur] = v[l - 1];
return ;
}
int mid = (l + r) >> 1;
build(cur << 1, l, mid, v);
build(cur << 1 | 1, mid + 1, r, v);
update(cur);
}
void apply(int ql, int qr, int v, int cur, int l, int r) {
if(ql <= l && r <= qr) return put(cur, v);
int mid = (l + r) >> 1; down(cur);
if(ql <= mid) apply(ql, qr, v, cur << 1, l, mid);
if(mid < qr) apply(ql, qr, v, cur << 1 | 1, mid + 1, r);
update(cur);
}
void upt(int p, pr v, int cur, int l, int r) {
if(l == r) return void(sgt[cur] = v);
int mid = (l + r) >> 1; down(cur);
if(p <= mid ) upt(p, v, cur << 1, l, mid);
else upt(p, v, cur << 1 | 1, mid + 1, r);
update(cur);
}
pr qpre(int p, int cur, int l, int r) {
if(l == r) return sgt[cur];
int mid = (l + r) >> 1; down(cur);
if(p <= mid) {
return qpre(p, cur << 1, l, mid);
} else {
return std::max(qpre(p, cur << 1 | 1, mid + 1, r), sgt[cur << 1]);
}
}
pr qsuf(int p, int cur, int l, int r) {
if(l == r) return sgt[cur];
int mid = (l + r) >> 1; down(cur);
if(p > mid) {
return qsuf(p, cur << 1 | 1, mid + 1, r);
} else {
return std::max(qsuf(p, cur << 1, l, mid), sgt[cur << 1 | 1]);
}
}
pr qry(int ql, int qr, int cur, int l, int r) {
if(ql <= l && r <= qr) return sgt[cur];
int mid = (l + r) >> 1; down(cur);
pr res(-1e18,-1);
if(ql <= mid) res = std::max(res, qry(ql, qr, cur << 1, l, mid));
if(mid < qr) res = std::max(res, qry(ql, qr, cur << 1 | 1, mid + 1, r));
return res;
}
pr qpre(int p) { return qpre(p, 1, 1, n); };
pr qsuf(int p) { return qsuf(p, 1, 1, n); };
pr qry(int l, int r) { return qry(l, r, 1, 1, n); };
void apply(int l, int r, int v) { apply(l, r, v, 1, 1, n); };
void upt(int p, pr v) { upt(p, v, 1, 1, n); };
void init(int n, std::vector<pr> v) {
assert(n == v.size());
this -> n = n;
add.resize(n << 2);
sgt.resize(n << 2);
build(1, 1, n, v);
}
} up[N], down[N], all;
struct edge {
int to, nxt, v;
} e[N << 1];
int h[N], num;
void link(int x, int y, int v) {
e[++num] = {y, h[x], v}, h[x] = num;
e[++num] = {x, h[y], v}, h[y] = num;
}
int st[20][N], dfn[N], top[N], son[N], size[N], anc[N];
ll dep[N], a[N];
int min(int x, int y) {
return dfn[x] < dfn[y] ? x : y;
}
int lca(int x, int y) {
if(dfn[x] > dfn[y]) std::swap(x, y);
if(x == y) return x;
const int lg = std::__lg(dfn[y] - dfn[x]);
return min(st[lg][dfn[x]], st[lg][dfn[y] - (1 << lg)]);
}
void dfs0(int x, int fa = 0) {
size[x] = 1;
for(int i = h[x];i;i = e[i].nxt) if(e[i].to != fa) {
dep[e[i].to] = dep[x] + e[i].v;
dfs0(e[i].to, x);
size[x] += size[e[i].to];
if(size[e[i].to] > size[son[x]]) {
son[x] = e[i].to;
}
}
}
int cnt;
void dfs1(int x, int top, int fa = 0) {
st[0][cnt] = fa, dfn[x] = ++ cnt;
::top[x] = top; anc[x] = fa;
if(son[x]) dfs1(son[x], top, x);
for(int i = h[x];i;i = e[i].nxt) if(e[i].to != fa && e[i].to != son[x]) {
dfs1(e[i].to, e[i].to, x);
}
}
pr qlight(int x) {
int L = dfn[x] + 1, R = dfn[x] + size[x] - 1;
pr res(dep[x]-a[x], x);
if(son[x]) L = dfn[son[x]] + size[son[x]];
if(L <= R) res = std::max(res, all.qry(L, R));
res.first -= dep[x];
return res;
}
int n, q;
void addsub(int y, ll v) {
int L = dfn[y], R = dfn[y] + size[y] - 1;
all.apply(L, R, -v);
if(L < R) tag.add(L + 1, R, v);
int tp = top[y];
up[tp].apply(dfn[y] - dfn[tp] + 1, up[tp].n, -v);
down[tp].apply(dfn[y] - dfn[tp] + 1, down[tp].n, -v);
for(;y = anc[top[y]];) {
tp = top[y];
pr u = qlight(y), d = u;
ll TAG = tag.qry(dfn[tp]);
u.first -= dep[y], u.first += TAG;
up[tp].upt(dfn[y] - dfn[tp] + 1, u);
d.first += dep[y], d.first += TAG;
down[tp].upt(dfn[y] - dfn[tp] + 1, d);
}
}
pr ex(int x, int s) {
int L = dfn[x] + 1, R = dfn[x] + size[x] - 1;
if(son[x]) L = dfn[son[x]] + size[son[x]];
pr ans(dep[x]-a[x], x);
if(L <= R) {
if(!s) {
ans = std::max(ans, all.qry(L, R));
} else {
if(L < dfn[s]) ans = std::max(ans, all.qry(L, dfn[s] - 1));
if(dfn[s] + size[s] <= R) ans = std::max(ans, all.qry(dfn[s] + size[s], R));
}
}
ans.first -= dep[x];
return ans;
}
pr qry(int x) {
ll DX = dep[x];
auto ans = all.qry(dfn[x], dfn[x] + size[x] - 1);
ans.first -= dep[x];
int tp = top[x];
int la = 0;
for(;x;la = tp, x = anc[tp], tp = top[x]) {
int pos = dfn[x] - dfn[tp] + 1;
ll TAG = tag.qry(dfn[tp]);
if(pos > 1) {
pr u = up[tp].qpre(pos - 1);
u.first += dep[x]; u.first += (DX - dep[x]); u.first -= TAG;
ans = std::max(ans, u);
}
if(pos < down[tp].n) {
pr d = down[tp].qsuf(pos + 1);
d.first -= dep[x]; d.first += (DX - dep[x]); d.first -= TAG;
ans = std::max(ans, d);
}
auto res = ex(x, la);
res.first += DX - dep[x];
ans = std::max(ans, res);
}
return ans;
}
int main() {
#ifdef zqj
freopen("1.in","r",stdin);
#endif
std::ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> q;
for(int i = 1;i <= n;++i) {
cin >> a[i];
}
for(int i = 2, fa, v;i <= n;++i) {
cin >> fa >> v;
link(fa, i, v);
}
dfs0(1), dfs1(1, 1);
std::vector<pr> A(n);
for(int i = 1;i <= n;++i) {
A[dfn[i] - 1] = {dep[i] - a[i], i};
}
all.init(n, A);
for(int i = 1;i <= n;++i) if(i == top[i]) {
std::vector<int> v;
std::vector<pr> u, d;
for(int x = i;x;x = son[x]) {
v.push_back(x);
pr z = qlight(x);
z.first -= dep[x];
u.push_back(z);
z.first += dep[x] * 2;
d.push_back(z);
}
up[i].init(v.size(), u);
down[i].init(v.size(), d);
}
for(int i = 1;i < 20;++i) {
for(int j = 1;j + (1 << i) - 1 < n;++j) {
st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
}
}
auto d = [&](int x, int y) {
return dep[x] + dep[y] - dep[lca(x, y)] * 2 - a[y];
};
for(int i = 1, x, y, v;i <= q;++i) {
cin >> x >> y >> v;
addsub(y, v);
/*
for(int j = 1;j <= n;++j)
if(dfn[y] <= dfn[j] && dfn[j] < dfn[y] + size[y])
a[j] += v;
*/
auto res = qry(x);
cout << res.second << ' ' << res.first << '\n';
/*
//TODO
assert(d(x, res.second) == res.first);
for(int j = 1;j <= n;++j) {
assert(res.first >= d(x, j));
}
*/
}
}
/*
3 3
7 0 6
1 9
1 -5
1 2 7
2 3 1
3 1 9
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4ms
memory: 34204kb
input:
6 6 1 1 4 5 1 4 1 5 2 0 3 2 4 1 5 6 3 2 -100000 1 2 100000 1 1 0 2 2 66 3 1 5 4 4 -3
output:
6 100005 6 10 6 10 1 4 1 -1 1 1
result:
ok 6 lines
Test #2:
score: -100
Wrong Answer
time: 0ms
memory: 34172kb
input:
5 6 -10 0 2 -4 8 1 7 1 1 2 2 2 -2 1 1 100 2 1 -100 1 1 0 4 3 10 2 5 3 5 2 2
output:
1 10 1 17 4 13 1 19 1 17 1 15
result:
wrong answer 1st lines differ - expected: '4 -87', found: '1 10'