[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 }

 

posted @ 2017-06-07 13:03  Kirai  阅读(341)  评论(0编辑  收藏  举报