关于此题的B、C性质
查看原帖
关于此题的B、C性质
555381
zlttcl楼主2024/8/29 10:35

其实就是一条链。

我的代码是直接推导求树高公式的,在此数据下B、C性质稳定答案小 11,不知道为什么,求解答。

//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
typedef __int128 ll;
const int N = 1e5 + 10;
int n, f[N], stk[N], in[N];
vector<int> vec[N];
ll a[N], b[N], c[N], t[N], id[N];
bool vis[N];
inline ll read(){
	ll x = 0, m = 1;
	char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') m = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * m;
}
inline void write(ll x){
	if(x < 0){
		putchar('-');
		write(-x);
		return;
	}
	if(x >= 10) write(x / 10);
	putchar(x % 10 + '0');
}
inline void dfs(int u, int fa){
	f[u] = fa;
	for(int i = 0; i < vec[u].size(); ++ i){
		int v = vec[u][i];
		if(v == fa) continue;
		dfs(v, u);
	}
}
inline ll calc(int x, ll l, ll r){
	if(c[x] >= 0) return (r - l + 1) * (b[x] + (l + r) / 2 * c[x]);
	ll now = (1 - b[x]) / c[x];
	if(now < l) return r - l + 1;
	if(now > r) return (r - l + 1) * (b[x] + (l + r) / 2 * c[x]);
	return (now - l + 1) * (b[x] + (l + now) / 2 * c[x]) + r - now;
}
inline bool cmp(int x, int y){
	return t[x] < t[y];
}
inline bool check(int r){
	for(int i = 1; i <= n; ++ i){
		if(calc(i, 1, r) < a[i]) return 0;
		int L = 1, R = n;
		while(L < R){
			int mid = (L + R + 1) >> 1;
			if(calc(i, mid, r) >= a[i]) L = mid;
			else R = mid -  1;
		}
		id[i] = i, t[i] = L, vis[i] = 0;
	}
	sort(id + 1, id + 1 + n, cmp);
	int x = 0;
	for(int i = 1; i <= n; ++ i){
		int now = id[i], top = 0;
		while(!vis[now]) vis[stk[++ top] = now] = 1, now = f[now];
		while(top) if(t[stk[top --]] < (++ x)) return 0;
	}
	return 1;
}
signed main(){
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	n = read();
	bool flag = 1;
	for(int i = 1; i <= n; ++ i) a[i] = read(), b[i] = read(), c[i] = read();
	for(int i = 1; i < n; ++ i){
		int u = read(), v = read();
		vec[u].push_back(v), vec[v].push_back(u);
		++ in[u], ++ in[v];
	}
	for(int i = 1; i <= n; ++ i) flag &= (in[i] <= 2);
	dfs(1, 0), vis[0] = 1;
	int l = n, r = 1e9;
	while(l < r){
		int mid = (l + r) >> 1;
		if(check(mid)) r = mid;
		else l = mid + 1;
	}
	write(l - flag);
	return 0;
}


2024/8/29 10:35
加载中...