求调一个 D
  • 板块学术版
  • 楼主大眼仔Happy
  • 当前回复11
  • 已保存回复11
  • 发布时间2024/7/31 00:37
  • 上次更新2024/7/31 09:27:14
查看原帖
求调一个 D
537046
大眼仔Happy楼主2024/7/31 00:37

用的是二分答案的方法。

感觉挺好写并且挺直观的但是死活没调出来。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
#define ll long long
int inline read() {
	int num = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-')f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		num = (num << 3) + (num << 1) + (ch ^ 48);
		ch = getchar();
	}
	return num * f;
}
int n, tim, dfn[N];
ll ma, a[N], b[N], lazy[N];
vector<int>e[N];
void add(int u, int v) {
	e[u].emplace_back(v);
}
void init(int u) {
	dfn[++tim] = u;
	for(int v : e[u])init(v);
}
bool check(ll k) {
	for(int i = 1; i <= n; i++)b[i] = a[i];
	for(int i = 1; i <= n; i++)lazy[i] = 0;
	b[1] -= k;
	for(int i = 1; i <= n; i++) {
		int u = dfn[i];
		bool f = 0;
		lazy[u] += max(0ll, -b[u]);
		for(int v : e[u]) {
			f = 1;
			b[v] -= lazy[u];
			lazy[v] += lazy[u];
		}
		if(!f && b[u] < 0)return false;
	}
	return true;
}
void solve() {
	n = read(), ma = 0;
	for(int i = 1; i <= n; i++)e[i].clear();
	for(int i = 1; i <= n; i++)a[i] = read(), ma = max(ma, 2 * a[i]);
	for(int i = 2; i <= n; i++) add(read(), i);
	tim = 0, init(1);
	ll l = a[1], r = ma;
	while(l < r) {
		ll mid = l + r + 1 >> 1;
		if(check(mid))l = mid;
		else r = mid - 1;
	}
	printf("%lld\n", l);
}
int main() {
#ifdef file
	freopen("D.in", "r", stdin);
	freopen("D.out", "w", stdout);
#endif
	int T = read();
	while(T--)solve();
	return 0;
}
2024/7/31 00:37
加载中...