CodeForces 813B The Golden Age
题目里说满足n = x^a + y^b时,n就是不幸运年,然后给你x和y,要求你求出L到R区间的连续幸运年的最大长度是多少,如果幸运年不存在则输出0.
这题数据很大,把L到R遍历一遍肯定是不可行的,题目说了n最大是1e18.然后n可以由x和y的指数幂确定,我们可以先暴力求出x的指数幂大于1e18一点就可以了,x>=2,最多大概就是60多次方,对于x这个次方和y的次方都可以预处理出来。然后只要枚举x的幂指数和y的幂指数,判断一下是否在L到R区间,是的话说明是不幸运年,然后存到一个v数组里。这样就把L到R区间里所有的不幸运年都求出来了,接下来求最长的连续幸运年长度时,就相当于是求最长的区间的长度了,不过因为存在v数组里的年份(可能会有重复的年份,但是不会影响到结果)不一定是单调递增的,所以要先按升序排个序,然后特殊处理一下最早的不幸运年和L之间的幸运年的长度,还有最后一个不幸运年和R之间的幸运年长度,最后从头扫到尾求一下区间长度就行了.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll maxn=1e19;
ll x[65],y[65];
ll v[10000];
int main()
{
cout<<maxn<<endl;
ll a,b,low,up,maxx=-1,cnt=0;;
int ti1,ti2;
cin>>a>>b>>low>>up;
ti1=(int)(log(maxn*1.0)/log(a*1.0));//算出a的多少次才能达到1e18以上
ti2=(int)(log(maxn*1.0)/log(b*1.0));//同理
x[0]=1;
y[0]=1;
for(int i=1;i<=ti1;i++)//预处理
{
x[i]=x[i-1]*a;
}
for(int i=1;i<=ti2;i++)//预处理
{
y[i]=y[i-1]*b;
}
for(int i=0;i<=ti1;i++)
for(int j=0;j<=ti2;j++)
{
if((x[i]+y[j])>=low&&(x[i]+y[j])<=up)
{
v[cnt++]=(ll)(x[i]+y[j]);
}
}
sort(v,v+cnt);
if(cnt>0)
{
if(cnt==1)//就一个不幸运年,处理一个左右2个区间的幸运年长度就行了
cout<<max(v[0]-low,up-v[0])<<endl;
else
{
maxx=max(v[0]-low,up-v[cnt-1]);
for(int i=0;i<=cnt-2;i++)
maxx=max(v[i+1]-v[i]-1,maxx);
cout<<maxx<<endl;
}
}
else
cout<<up-low+1<<endl;
return 0;
}