QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#204951#7563. Fun on Treeucup-team1209#WA 4ms36532kbC++207.0kb2023-10-07 14:27:032023-10-07 14:27:03

Judging History

你现在查看的是最新测评结果

  • [2023-10-07 14:27:03]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:36532kb
  • [2023-10-07 14:27:03]
  • 提交

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;
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.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: 4ms
memory: 34296kb

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: 3ms
memory: 34456kb

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: -100
Wrong Answer
time: 0ms
memory: 36532kb

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:

3 10
6 11
3 10

result:

wrong answer 1st lines differ - expected: '2 10', found: '3 10'