S T4 45pts 求优化方法
  • 板块学术版
  • 楼主FFFFFAN
  • 当前回复7
  • 已保存回复8
  • 发布时间2023/10/26 22:23
  • 上次更新2023/11/2 11:16:56
查看原帖
S T4 45pts 求优化方法
240724
FFFFFAN楼主2023/10/26 22:23

两个 log 的做法,开了全局 __int128,第四个样例稳过,但是跑的很慢,加上各种小优化和换桶排序之后快了好几秒,但洛谷上还是 45pts。
个人认为应该不是写错了,单纯跑得慢,求助有没有有效地优化方法!(除了解一元二次方程……)

#include<cstdio>
#include<vector>
#include<algorithm>
#define N 100005
#define int __int128
using namespace std;

inline int read() {
	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<<3)+(x<<1)+(ch^48), ch=getchar();
	return x*f;
}

inline void write(int x) {
	if(x < 0)	putchar('-'), x=-x;
	if(x > 9)	write(x/10);
	putchar(x%10+'0');
}

struct Edge {
	int v, nex;
} e[N<<1];

int n, a[N], b[N], c[N], vis[N], fa[N], idx, h[N], lst[N], cnt, bs, pla[N];

inline void link(int u, int v) {
	e[++idx]={v, h[u]}, h[u]=idx;
	e[++idx]={u, h[v]}, h[v]=idx;
}

inline int calc(int i, int l, int r) {
	if(c[i] == 0)	return b[i]*(r-l+1);
	int p = (1-b[i])/c[i];
	if(c[i]>0 || r<p)	return b[i]*(r-l+1)+c[i]*(l+r)*(r-l+1)/2;
	else if(l > p)	return r-l+1;
	else	return b[i]*(p-l+1)+c[i]*(l+p)*(p-l+1)/2+r-p;
}

void dfs(int u) {
	for(int i=h[u]; i; i=e[i].nex) {
		if(e[i].v == fa[u])	continue;
		fa[e[i].v] = u;
		dfs(e[i].v);
	}
}

bool access(int u) {
	if(!vis[fa[u]])	if(!access(fa[u]))	return false;
	if(++cnt > lst[u])	return false;
	vis[u] = 1;
	return true;
}

vector<signed> bk[N];

bool check(int limit) {
	for(int i=0; i<n; ++i)	bk[i].clear();
	int pcnt = 0;
	for(int u=1; u<=n; ++u) {
		if(calc(u, 1, limit) < a[u])	return false;
		vis[u]=0, lst[u]=-1;
		int l=1, r=limit, mid;
		while(l <= r) {
			mid = (l+r)>>1;
			if(calc(u, mid, limit) >= a[u])	lst[u]=mid, l=mid+1;
			else	r = mid-1;
		}
		bk[lst[u]/bs].push_back(u);
	}
	for(int i=0; i<n; ++i) {
		sort(bk[i].begin(), bk[i].end(), [](int x, int y) {
			return lst[x] < lst[y];
		});
		for(auto x : bk[i])	pla[++pcnt] = x;
	}
	cnt = 0;
	for(int i=1; i<=pcnt; ++i) {
		if(vis[pla[i]])	continue;
		if(!access(pla[i]))	return false;
	}
	return true;
}

signed main() {
	n=read(), vis[0]=1, bs=1e9/n+1;
	for(int i=1; i<=n; ++i)	a[i]=read(), b[i]=read(), c[i]=read();
	for(int i=1; i<n; ++i)	link(read(), read());
	dfs(1);
	int l=1, r=1e9, mid, ans;
	while(l <= r) {
		mid = (l+r)>>1;
		if(check(mid))	ans=mid, r=mid-1;
		else	l = mid+1;
	}
	write(ans);
	return 0;
}
2023/10/26 22:23
加载中...