http://codeforces.com/contest/813/problem/B
【题意】
满足n=x^a+y^b的数字为不幸运数字,a,b都是非负整数;
求闭区间[l,r]上的最长的连续幸运数字的区间长度。
2 ≤ x, y ≤ 10^18, 1 ≤ l ≤ r ≤ 10^18
【思路】
因为x,y>=2,所以x^a<=10^18,a不超过60
那么我们可以枚举所有的x^i
【注意】
这道题对于数字的处理一定要特别小心。
1.
1 while (num <= 1e18) 2 num = num * x
1 while (num * x <= 1e18) 2 num = num * x
这两种写法都不对,都会爆ll,因为num*x已经爆了ll,变成了<1e18的数
正确写法是:
1 while(num<=1e18/x) 2 { 3 num*=x; 4 }
1 int p=floor(log(r)/log(x)); 2 int q=floor(log(r)/log(y));
写法二是用log求出个数后再for循环
2. pow函数精度不够,会WA
一开始我用了pow函数,结果WA了8发.....都是这个原因,后来手写了快速幂......以后不用这个函数了
1 ll fpow(ll x,int k) 2 { 3 long long res=1; 4 while(k) 5 { 6 if(k&1)res=res*x; 7 x=x*x; 8 k>>=1; 9 } 10 return res; 11 }
【Accepted】
1 #include <iostream> 2 #include <stdio.h> 3 #include <cmath> 4 #include <vector> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <queue> 9 #include <deque> 10 #include <stack> 11 #include <string> 12 #include <bitset> 13 #include <ctime> 14 #include<algorithm> 15 #include<cstring> 16 using namespace std; 17 typedef long long ll; 18 const int maxn=67; 19 ll a[maxn]; 20 ll b[maxn]; 21 ll x,y,l,r; 22 ll sum[maxn*maxn]; 23 ll fpow(ll x,int k) 24 { 25 long long res=1; 26 while(k) 27 { 28 if(k&1)res=res*x; 29 x=x*x; 30 k>>=1; 31 } 32 return res; 33 } 34 int main() 35 { 36 cin>>x>>y>>l>>r; 37 int p=floor(log(r)/log(x)); 38 int q=floor(log(r)/log(y)); 39 for(int i=0;i<=p;i++) 40 { 41 a[i]=fpow(x,i); 42 } 43 for(int i=0;i<=q;i++) 44 { 45 b[i]=fpow(y,i); 46 } 47 int cnt=0; 48 for(int i=0;i<=p;i++) 49 { 50 for(int k=0;k<=q;k++) 51 { 52 if(a[i]+b[k]<=r&&a[i]+b[k]>=l) 53 sum[cnt++]=a[i]+b[k]; 54 } 55 } 56 sort(sum,sum+cnt); 57 cnt=unique(sum,sum+cnt)-sum; 58 if(cnt==0) 59 { 60 cout<<r-l+1<<endl; 61 return 0; 62 } 63 ll ans=max(sum[0]-l,r-sum[cnt-1]); 64 for(int i=1;i<=cnt-1;i++) 65 { 66 ans=max(ans,sum[i]-sum[i-1]-1); 67 } 68 cout<<ans<<endl; 69 return 0; 70 }