Description
Input
Output
Sample Input
2
4 7
Sample Output
17
Data Constraint
分析:
n=2n=2 就是noipD1T1,直接输出x∗y−x−yx∗y−x−y。
考虑 n>2n>2 怎么做,此时x1<103x1<103。
我们设k=x1k=x1,a[i]a[i]为在mod kmod k意义下,余数为ii的最小的能被表示的数是多少。
因为有这一个数,如果能表示出a[i]a[i],那么a[i]+ka[i]+k也能被表示出,答案其实就是(maxk−1i=0a[i])−k(maxi=0k−1a[i])−k。
考虑怎样处理出aa,显然,然后依次加入第22个到第个数。我们先把前i−1i−1个数得到的ii放进一个堆里,每次弹出一个最小的数,判断能否去更新a[(i+d) mod k]a[(i+d) mod k],假设当前插入的是dd,如果能更新,就把这个新的也插入到堆里,这样就做完了。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#define LL long long
const int maxn=1e5+7;
using namespace std;
LL n;
LL a[10],h[maxn];
struct rec{
LL x,k;
};
bool operator <(rec a,rec b)
{
return a.x>b.x;
}
priority_queue <rec> q;
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
scanf("%lld",&n);
for (LL i=1;i<=n;i++) scanf("%lld",&a[i]);
if (n==2) printf("%lld",a[1]*a[2]-a[1]-a[2]);
else
{
for (LL i=1;i<a[1];i++) h[i]=1e18;
for (LL i=2;i<=n;i++)
{
for (LL j=0;j<a[1];j++) q.push((rec){h[j],j});
while (!q.empty())
{
rec d=q.top();
q.pop();
LL k=d.k,l=(k+a[i])%a[1];
if (h[l]>h[k]+a[i])
{
h[l]=h[k]+a[i];
q.push((rec){h[l],l});
}
}
}
LL ans=0;
for (LL i=0;i<a[1];i++) ans=max(ans,h[i]-a[1]);
printf("%lld",ans);
}
}