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;

}
原文地址:https://www.cnblogs.com/eason9906/p/11754964.html