被卡常力求条(本地编译不了int128)
查看原帖
被卡常力求条(本地编译不了int128)
340732
xinlin楼主2024/10/22 16:42
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define int __int128
//#define int long long
const int N = 100005;
const int MAXR = 1e9 + 5;
int a[N], b[N], c[N];
int n;
void write(int x) {
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0'); return;
}
inline int sum(int x) {
	return x * (x + 1) / 2;
}
inline int Get(int A, int B, int C, int d) {
	if(C >= 0) return d * B + sum(d) * C;
//	int ed = B / (-C);
//	if(B % (-C) == 0) --ed;
	int ed = (1 - B) / C;
	if(d <= ed) return d * B + sum(d) * C;
	else return ed * B + sum(ed) * C + (d - ed);
}
inline int Get_limit(int x, int d) {
	int l = 0, r = d + 1, mid;
	int tot = Get(a[x], b[x], c[x], d);
	while(l < r) {
		mid = (l + r) >> 1;
		if((tot - Get(a[x], b[x], c[x], mid)) >= a[x]) l = mid + 1;
		else r = mid;
	}
	return l;
}
int head[N], cnt = 0;
int to[N * 2], nxt[N * 2];
void add(int u, int v) {
	to[++cnt] = v;
	nxt[cnt] = head[u];
	head[u] = cnt;
}

int lim[N];
bool vis[N];
inline void Get_son_lim(int x) {
	vis[x] = true;
	for(int i = head[x]; i; i = nxt[i]) {
		int v = to[i];
		if(vis[v]) continue;
		Get_son_lim(v);
		lim[x] = std::min(lim[x], lim[v]);
	}
	return;
}
std::priority_queue<std::pair<int, int> > q;
inline bool check(int d) {
	while(!q.empty()) q.pop();
	for(int i = 1; i <= n; ++i) lim[i] = Get_limit(i, d);
	//最晚在lim[i]种 
	memset(vis, 0, sizeof(vis)); Get_son_lim(1);
	memset(vis, 0, sizeof(vis));
	q.push(std::make_pair(lim[1], 1));
	int nowday = 0;
	while(!q.empty()) {
		++nowday;
		int p = q.top().second;
		vis[p] = true;
		q.pop();
		if(lim[p] < nowday) return false;
		for(int i = head[p]; i; i = nxt[i]) {
			int v = to[i];
			if(vis[v] == false) {
				vis[v] = true;
				q.push(std::make_pair(-lim[v], v));
			}
		}
	}
	return true;
}
int Get_Ans(){
	int l = 0, r = MAXR, mid;
	while(l < r){
		mid = (l + r) >> 1;
		if(check(mid)) r = mid;
		else l = mid + 1;
	}
	return l;
}
signed main(){
//	freopen("tree3.in", "r", stdin);
	scanf("%lld", &n); 

	for(int i = 1; i <= n; ++i) 
		scanf("%lld%lld%lld", &a[i], &b[i], &c[i]);
	int u, v;
	for(int i = 1; i < n; ++i) {
		scanf("%lld%lld", &u, &v);
		add(u, v); add(v, u);
	}
//	printf("%lld", Get_Ans());
	write(Get_Ans());
//	printf("%d", check(5));
//	printf("%lld", Get_limit(4, 5));
//	printf("%lld", Get(4, ));
	
	return 0;
}
/*
4
12 1 1
2 4 -1
10 3 0
7 10 -2
1 2
1 3
3 4
*/

加inline后:https://www.luogu.com.cn/record/183995199 加inline前: https://www.luogu.com.cn/record/183993585

2024/10/22 16:42
加载中...