【洛谷P1080】国王游戏

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

题目链接

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

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

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

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

我们把\(\frac{P}{X_bY_b}\)提出来,按照\(Y_b+X_a\times X_b\)\(X_b+Y_a\times 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;
}
posted @ 2018-10-15 20:44  yjk  阅读(171)  评论(0编辑  收藏  举报