MnZn求助精度问题
查看原帖
MnZn求助精度问题
367387
cainiaoshanglu楼主2022/6/6 20:36

用了long double和eps,貌似没有啥其他问题啊

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define int long long
#define double long double
using namespace std;

const double eps=1e-9;
void read(int &x){
	x=0;
	char c=getchar();
	while(!('0'<=c && c<='9')){
		c=getchar();
	}
	while('0'<=c && c<='9'){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
}
int n,tp=0;
double dp[100010];
struct Node{
	double x,y,a,b,r;
	int id;
	Node(){}
} q[100010],st[100010];
double slp(Node u,Node v){
	if(fabs(u.x-v.x)<=eps){
		return 1e9;
	}
	return (u.y-v.y)/(u.x-v.x);
}
bool cmp1(Node u,Node v){
	return u.a*v.b>v.a*u.b;
}
bool cmp2(Node u,Node v){
	return u.x<v.x;
}
bool cmp3(Node u,Node v){
	return u.id<v.id;
}
void cdq(int l,int r){
	if(l==r){
		dp[l]=max(dp[l],dp[l-1]);
		q[l].y=dp[l]/(q[l].a*q[l].r+q[l].b);
		q[l].x=q[l].y*q[l].r;
	}else{
		int mid=(l+r)>>1;
		sort(q+l,q+r+1,cmp3);
		cdq(l,mid);
		tp=0;
		for(int i=l;i<=mid;i++){
			while(tp>=2 && slp(st[tp],q[i])+eps>slp(st[tp-1],st[tp])){
				tp--;
			}
			st[++tp]=q[i];
		}
		for(int i=mid+1;i<=r;i++){
			while(tp>=2 && -(q[i].a/q[i].b)+eps>=slp(st[tp-1],st[tp])){
				tp--;
			}
			dp[q[i].id]=max(dp[q[i].id],st[tp].x*q[i].a+st[tp].y*q[i].b);
		}
		cdq(mid+1,r);
		sort(q+l,q+r+1,cmp2);
	} 
}
signed main(){
	read(n);
	scanf("%Lf",dp);
	for(int i=1;i<=n;i++){
		scanf("%Lf %Lf %Lf",&q[i].a,&q[i].b,&q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+n+1,cmp1);
	cdq(1,n);
	printf("%.3Lf",dp[n]);
	return 0;
}
2022/6/6 20:36
加载中...