[CF813B] The Golden Age(数学,枚举,溢出trick)
题目链接:http://codeforces.com/contest/813/problem/B
题意:给定x,y,l,r,求[l,r]区间内满足n!=x^a+y^b的最长子序列的长度。2<=x,y<=1e18
稍微分析下会发现,这个x^a,y^b中a、b不会太大,因为2^63大约为1e19。
枚举所有x^a, y^b,再求和就可以。
但是可能会溢出,要稍微抠一下才能过。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef unsigned long long LL; 5 const int maxn = 1100; 6 LL x, y, l, r; 7 LL X[maxn], Y[maxn]; 8 vector<LL> ret; 9 int n, m; 10 11 int main() { 12 // freopen("in", "r", stdin); 13 while(cin >> x >> y >> l >> r) { 14 memset(X, 0, sizeof(X)); 15 memset(Y, 0, sizeof(Y)); 16 ret.clear(); 17 X[0] = 1, Y[0] = 1; 18 X[1] = x, Y[1] = y; 19 for(n = 2; x * X[n-1] >= 0 && x * X[n-1] <= (LL)1e18; n++) { 20 if(X[n-1] % x != 0 || X[n-1] == 0) break; 21 X[n] = x * X[n-1]; 22 } 23 for(m = 2; y * Y[m-1] >= 0 && y * Y[m-1] <= (LL)1e18; m++) { 24 if(Y[n-1] % y != 0 || X[n-1] == 0) break; 25 Y[m] = y * Y[m-1]; 26 } 27 n--; m--; 28 for(int i = 0; i <= n; i++) { 29 for(int j = 0; j <= m; j++) { 30 if((i==0||X[i]%x==0)&&(j==0||Y[j]%y==0)) { 31 if(l <= X[i] + Y[j] && X[i] + Y[j] <= r) { 32 ret.push_back(X[i]+Y[j]); 33 } 34 } 35 } 36 } 37 ret.push_back(l-1); ret.push_back(r+1); 38 sort(ret.begin(), ret.end()); ret.erase(unique(ret.begin(), ret.end()), ret.end()); 39 // for(auto x : ret) cout << x << " "; 40 // cout << endl; 41 LL seg = 0; 42 for(int i = 1; i < ret.size(); i++) { 43 seg = max(seg, ret[i]-ret[i-1]-1); 44 } 45 cout << seg << endl; 46 } 47 return 0; 48 }