50分TLE求助!
查看原帖
50分TLE求助!
727076
hexz01楼主2023/11/5 20:21
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <stack>
using namespace std;
typedef __int128 ll;
typedef pair<int, int> PII;
#define mp make_pair
const int N=1e5+7;
int n;
int now_time=0;
ll a[N];
int b[N], c[N];
int s[N], t[N], maxii[N];
int fa[N];bool vis[N];
priority_queue<PII, vector<PII>, greater<PII> > q;
stack<int> st;
ll check(ll x, ll l, ll r){
	ll maxi=maxii[x];
	if(maxi<l){
		return r-l+1;
	}else if(maxi>r){
		return b[x]*(r-l+1)+c[x]*(l+r)*(r-l+1)/2;
	}else{
		return b[x]*(maxi-l+1)+c[x]*(l+maxi)*(maxi-l+1)/2+r-maxi;
	}
}
int lst_tim(int x, int M){
	int l=1, r=M, max1=l-1;
	while(l<=r){
		ll mid=(l+r)>>1;
		if(check(x, mid, M)>=a[x]){
			l=mid+1;
			max1=max(max1, (int)mid);
		}else
			r=mid-1;
	}
	return max1;
}
bool specail_A(){
	vis[0]=1;
	while(q.size()){
		PII now=q.top();q.pop();
		if(vis[now.second])
			continue;
		int u=now.second;
		while(!vis[u])
			st.push(u), u=fa[u];
		while(st.size()){
			int v=st.top();st.pop();
			s[v]=++now_time;
			vis[v]=1;
			if(s[v]>t[v])
				return 0;
		}
	}
	return 1;
}
bool CHECK(int x){
	now_time=0;
	memset(vis, 0, sizeof(vis));
	for(int i=1;i<=n;i++)
		t[i]=lst_tim(i, x);
	while(q.size()) q.pop();
	while(st.size()) st.pop();
	for(int i=1;i<=n;i++)
		q.push(mp(t[i], i));
	return specail_A();
}
int main(){
	//freopen("tree.in", "r", stdin);
	//freopen("tree.out", "w", stdout);
	scanf("%d", &n);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld%lld", a+i, b+i, c+i);
	for(int i=1;i<n;i++){
		int x, y;
		scanf("%d%d", &x, &y);
		fa[y]=x;
	}
	for(int i=1;i<=n;i++)
		maxii[i]=(c[i]>=0?int(1e9+7):(1-b[i])/c[i]);
	int L=n, R=1e9;
	int min1=R+1;
	while(L<=R){
		int mid=(L+R)>>1;
		if(CHECK(mid)){
			R=mid-1;
			min1=min(min1, mid);
		}else{
			L=mid+1;
		}
	}
	cout<<min1<<endl;
	return 0;
}

所有TLE的点都是1.01s~1.07s

2023/11/5 20:21
加载中...