QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#204958 | #7563. Fun on Tree | ucup-team1209# | WA | 1110ms | 114552kb | C++20 | 7.1kb | 2023-10-07 14:29:10 | 2023-10-07 14:29:10 |
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, A;
struct pr {
ll first; int second;
};
bool operator < (const pr & x, const pr & y) {
if(x.first != y.first)
return x.first < y.first;
return x.second > y.second;
}
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.qry(dfn[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.qry(dfn[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};
::A.add(dfn[i], dfn[i], a[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);
::A.add(dfn[y], dfn[y] + size[y] - 1, 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: 0ms
memory: 34236kb
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: 0
Accepted
time: 4ms
memory: 38296kb
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:
4 -87 1 17 4 13 1 19 1 17 1 15
result:
ok 6 lines
Test #3:
score: 0
Accepted
time: 4ms
memory: 34288kb
input:
6 3 0 0 0 0 0 0 1 10 1 10 1 -100 4 10 4 11 1 1 0 4 1 0 1 4 1000
output:
2 10 6 11 2 10
result:
ok 3 lines
Test #4:
score: 0
Accepted
time: 4ms
memory: 34272kb
input:
2 0 1 1 1 3
output:
result:
ok 0 lines
Test #5:
score: -100
Wrong Answer
time: 1110ms
memory: 114552kb
input:
200000 200000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 ...
output:
119017 15000000000 120167 17000000000 119017 15000000000 119017 15000000000 120167 17000000000 120167 15000000000 120167 16000000000 119017 17000000000 119017 16000000000 119017 12000000000 119017 17000000000 120167 16000000000 120167 14000000000 120167 17000000000 120167 18000000000 120167 16000000...
result:
wrong answer 20642nd lines differ - expected: '119017 16000000000', found: '140085 16294967296'