Codeforces 813B The Golden Age(数学+枚举)

题目大意:如果一个数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 }

 

转载于:https://www.cnblogs.com/fu3638/p/7117154.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值