【洛谷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;
}