WA 40分求调
查看原帖
WA 40分求调
479448
fire_and_sweets楼主2024/10/16 23:40

萌新刚学 OI\text{OI} 101010^{-10} 秒,就被这道题难住了,4040 分一直卡不过去,麻烦大佬帮我看一下问题。

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010, M = 2 * N, INF = 1e12;
int T, n, a[N], h[N], e[M], ne[M], idx, fa[N], f[N], nw[N];
void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int myabs(int x) {
	if (x < 0) x = -x;
	return x;
}
typedef pair<int, int> PII; 
vector<PII> v[N]; // first: f; second: nw
bool check(int u, int S) {
	int sum = 0;
	for (int i = 0; i < v[u].size(); i ++ ) sum += v[u][i].first;
	if (sum < S) return false;
	sum = 0;
	for (int i = 0; i < v[u].size(); i ++ ) {
		int nw = v[u][i].second;
		sum += max(0ll, S - myabs(nw));
	} 
	if (sum > S) return false;
	return true;
}
void dfs(int u, int father) {
	v[u].clear();
	for (int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		if (j == father) continue;
		dfs(j, u);
		v[u].push_back({f[j], nw[j]});
	}
	if (v[u].empty()) {
		f[u] = INF;
		return;
	}
	int l = 0, r = INF;
	f[u] = 0;
	while (l <= r)
	{
		int mid = l + r >> 1;
		if (check(u, mid)) f[u] = mid, l = mid + 1;
		else r = mid - 1;
	}
}
void solve() {
	cin >> n;
	for (int i = 1; i <= n; i ++ ) h[i] = -1;
	idx = 0;
	for (int i = 2, x; i <= n; i ++ ) {
		cin >> fa[i];
		add(fa[i], i), add(i, fa[i]);
	}
	for (int i = 1; i <= n; i ++ ) cin >> a[i];
	for (int i = 1; i <= n; i ++ ) nw[i] = a[i] - a[fa[i]];
	for (int i = 2; i <= n; i ++ )
		if (nw[i] > 0) {
			cout << "Shuiniao\n";
			return;
		}
	if (nw[1] <= 0) {
		cout << "Huoyu\n";
		return;
	}
	dfs(1, -1);
	if (f[1] >= myabs(nw[1])) cout << "Huoyu\n";
	else cout << "Shuiniao\n";
}
signed main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T >> T;
	while (T -- ) solve();
	return 0;
} 
2024/10/16 23:40
加载中...