【洛谷P1080】国王游戏

~~这是一个国王、n个$Dark$臣、和他们的小左小右$van$游戏的故事~~

题目链接

考虑两个(Dark)(X)(Y),设他们前面的(Dark)臣左手乘积为P

考虑两种先后顺序的贡献:

[X-Y:frac{P}{X_b}+frac{P imes X_a}{Y_b}=P imes frac{Y_b+X_a imes X_b}{X_bY_b} ]

[Y-X:frac{P}{Y_b}+frac{P imes Y_a}{X_b}=P imes frac{X_b+Y_a imes Y_b}{X_bY_b} ]

我们把(frac{P}{X_bY_b})提出来,按照(Y_b+X_a imes X_b)(X_b+Y_a imes Y_b)的大小排序即可

还要写毒瘤高精度

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define int long long
const int N=1010,M=100010;
int n;
struct NODE{
	int a,b;
} m[N];
struct gjint{
	int d[M],len;
} ans,prod,t;
bool cmp(NODE x,NODE y){
	return y.b+x.a*x.b<x.b+y.a*y.b;
}
inline void cheng(gjint &a,int x){
	int l=a.len;
	for(int i=1;i<=l;i++)
		a.d[i]*=x;
	for(int i=1;i<=l;i++)
		if(a.d[i]>9){
			a.d[i+1]+=a.d[i]/10;
			a.d[i]%=10;
		}
	if(a.d[l+1]) ++l;
	while(a.d[l]>9){
		a.d[l+1]+=a.d[l]/10;
		a.d[l]%=10; ++l;
	}
	a.len=l;
}
inline void chu(gjint a,int x,gjint &b){
	int now=a.len,rest=a.d[now];
	while(rest<x&&now)
		rest=rest*10+a.d[--now];
	b.len=now;
	while(now){
		b.d[now]=rest/x;
		rest%=x;
		rest=rest*10+a.d[--now];
	}
}
inline bool dayu(gjint a,gjint b){
	if(a.len!=b.len) return a.len>b.len;
	for(int i=a.len;i>=1;i--)
		if(a.d[i]!=b.d[i]) return a.d[i]>b.d[i];
	return 0;
}
inline void copy(gjint a,gjint &b){
	b.len=a.len;
	for(int i=1;i<=b.len;i++)
		b.d[i]=a.d[i];
}
inline void print(gjint a){
	for(int i=a.len;i>=1;i--)
		printf("%d",a.d[i]);
	puts("");
}
#undef int
int main()
#define int long long
{
	scanf("%lld",&n);
	++n;
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&m[i].a,&m[i].b);
	sort(m+2,m+1+n,cmp);
	prod.d[1]=1; prod.len=1;
	ans.d[1]=0; ans.len=1;
	cheng(prod,m[1].a);
	for(int i=2;i<=n;i++){
		chu(prod,m[i].b,t);
		if(dayu(t,ans)) copy(t,ans);
		cheng(prod,m[i].a); 
	}
	print(ans);
	return 0;
}
原文地址:https://www.cnblogs.com/yjkhhh/p/9794462.html