社区讨论

2个log被卡到55求助

P9755[CSP-S 2023] 种树参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mhke3uwx
此快照首次捕获于
2025/11/04 17:52
4 个月前
此快照最后确认于
2025/11/04 17:52
4 个月前
查看原帖
复杂度应该为logT(nlogn+nlogT)logT(nlogn+nlogT)
T的点差了100ms以内 求优化
CPP
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define int __int128
const int N = 1e5 + 10 ;
int n,ans;
struct stu
{
	int a,b,c;
	int t;//开始为 1 的时间
	int date;
	int dep;
	int F;
	int tr;
}tree[N];
vector<int> g[N];
int stk[N],top;
bool f[N];
void dfs(int x,int fa)
{
	tree[x].dep=tree[fa].dep+1;
	for(auto y:g[x]) 
		if(y!=fa) 
		{
			dfs(y,x);
			tree[y].F=x; 
		}
}
void init()
{
	for(int i=1;i<=n;i++) 
		if(tree[i].c<0) 
			tree[i].t=(tree[i].b)/(-tree[i].c)+((tree[i].b)%(-tree[i].c)!=0); 
}
bool ck(int l,int r,int idx)
{
	if(r<tree[idx].t) return (l+r)*(r-l+1)/2*tree[idx].c+tree[idx].b*(r-l+1)>=tree[idx].a ;
	if(l>=tree[idx].t) return r-l+1>=tree[idx].a;
	else 	 return r-tree[idx].t+1+(l+tree[idx].t-1)*(tree[idx].t-l)/2*tree[idx].c+tree[idx].b*(tree[idx].t-l)>=tree[idx].a ;  
}
bool cmp(stu x,stu y)
{
	return x.date<y.date;
}
bool cmp2(stu x,stu y)
{
	return x.tr<y.tr;
}
bool check(int mid)
{ 
	for(int i=1;i<=n;i++)
	{
		if(tree[i].c==0) tree[i].date=mid-(tree[i].a/tree[i].b+(tree[i].a%tree[i].b!=0))+1 ;
		else if(tree[i].c>0)
		{
			int l=1,r=mid,s;
			if( ( ( 1 + mid ) * mid / 2 * tree[i].c + tree[i].b * mid ) >= tree[i].a )
			{
				while(l<=r)
				{
					int m= l + r >> 1 ; 
					if(((m+mid)*(mid-m+1)/2*tree[i].c+tree[i].b*(mid-m+1))>=tree[i].a) l=m+1,s=m;
					else r=m-1;
				}				
			}
			else return false ; 
			tree[i].date=s;
		}
		else if(tree[i].c<0)
		{
			int l=1,r=mid,s;
			if(ck(1,mid,i))
			{
				while(l<=r)
				{
					int m=l+r>>1;
					if(ck(m,mid,i)) l=m+1,s=m;
					else r=m-1;
				}				
			}
			else return false ;
			tree[i].date=s;
		}
	}
	sort(tree+1,tree+1+n,cmp);
	queue<int> q;
	for(int i=1;i<=n;i++) q.push(tree[i].tr);
	sort(tree+1,tree+1+n,cmp2);
	int t = 1 ;
	for(int i=1;i<=n;i++) f[i]=0;
	while(!q.empty())
	{
		int i=q.front(); q.pop();
		top = 0 ;
		if(f[i]) continue;
		else
		{
			int x = i ;
			while(x)
			{
				if(f[x]) break;	
				f[x]=1;
				stk[++top]=x;				
				x=tree[x].F;
			}
		}		
		while(top)
		{
			if(t>tree[stk[top]].date) return false;
			t++;
			top--;
		}
	}
	return true ;
}
void read(int &a)
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    a=x*f;
}
void write(int x) 
{
    if(x<0) {putchar('-'),x=-x;}
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
signed main()
{ 
	read(n);
	for(int i=1;i<=n;i++) read(tree[i].a),read(tree[i].b),read(tree[i].c),tree[i].tr=i; 
	for(int i=1;i<n;i++)
	{
		int u,v;
		read(u); read(v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	init();
	dfs(1,0);
	int l=n,r=1e9;
	while(l<=r)
	{
		int mid = l + r >> 1 ; 
		bool fl = check(mid) ;
		if(fl) r = mid - 1,ans=mid ;  
		else l = mid + 1 ; 
	} 
	write(l);
}

回复

7 条回复,欢迎继续交流。

正在加载回复...