题目大意:如果一个数t=x^a+y^b(a,b都是大于等于0的整数)那就是一个unlucky数字。给你x,y,l,r(2 ≤ x, y ≤ 10^18, 1 ≤ l ≤ r ≤ 10^18),求出l到r内没有unlucky数字的最小区间。
解题思路:可以知道a,b最多也不会超过60(2^60>1e18),所以可以直接枚举x^a+y^b的值存到vector里,然后排序,遍历一下vector,找出v[i+1]-v[i]-1(因为两端都是unlucky数字所以要两个端点都不算在长度内)最大的区间即可。要注意vector为空和两个端点的特判。还有数字的溢出问题,这个没办法直接判断是否溢出,可以通过使用一个d=r,比如每次x次方加一的时候,就将d/x,当d==0说明x^a已经超出r的范围了。
代码:
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 7 vector<ll>v; 8 9 int main(){ 10 ll x,y,l,r; 11 cin>>x>>y>>l>>r; 12 ll tx,ty; 13 ll d1=r; 14 for(int i=0;i<=61;i++){ 15 if(i!=0) 16 d1/=x; 17 if(d1==0) 18 break; 19 if(i==0) 20 tx=1; 21 else 22 tx*=x; 23 ll d2=r; 24 for(int j=0;j<=61;j++){ 25 if(j!=0) 26 d2/=y; 27 if(d2==0) 28 break; 29 if(j==0) 30 ty=1; 31 else 32 ty*=y; 33 if(tx+ty>=l&&tx+ty<=r){ 34 v.push_back(tx+ty); 35 } 36 } 37 } 38 //vector为空的情况 39 if(!v.size()){ 40 cout<<r-l+1<<endl; 41 return 0; 42 } 43 44 ll ans=0; 45 sort(v.begin(),v.end()); 46 for(int i=0;i<v.size();i++){ 47 //如果l不是unlucky数字,那就额外计算v[0]-l这段区间 48 if(i==0&&v[0]!=l) 49 ans=max(ans,v[i]-l); 50 //如果r不是unlucky数字,就额外计算r-v[v.size()-1]这段区间 51 if(i==v.size()-1){ 52 if(!sign2) 53 ans=max(ans,r-v[i]); 54 } 55 else 56 ans=max(ans,v[i+1]-v[i]-1); 57 } 58 cout<<ans<<endl; 59 }