Codeforces 758F Geometrical Progression

Geometrical Progression

n == 1的时候答案为区间长度, n == 2的时候每两个数字都可能成为答案,

我们只需要考虑 n == 3的情况, 我们可以枚举公差, 其分子分母都在sqrt(1e7)以内,

然后暴力枚举就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1);

int n, l, r;

struct Node {
    int x, y;
    bool operator < (const Node& rhs) const {
        return x * rhs.y < rhs.x * y;
    }
    bool operator == (const Node& rhs) const {
        return x * rhs.y == rhs.x * y;
    }
};

vector<Node> vc;

int Power(int a, int b) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = ans * a;
        a = a * a; b >>= 1;
    }
    return ans;
}
int main() {
    scanf("%d%d%d", &n, &l, &r);
    if(n > 25) {
        puts("0");
    } else if(n == 1) {
        printf("%d\n", r - l + 1);
    } else if(n == 2) {
        printf("%lld\n", 1ll * (r - l + 1) * (r - l));
    } else {
        for(int i = 1; i * i <= r; i++) {
            for(int j = 1; j * j <= r; j++) {
                if(i == j) continue;
                int x = i, y = j;
                int gcd = __gcd(x, y);
                vc.push_back(Node{x / gcd, y / gcd});
            }
        }
        sort(vc.begin(), vc.end());
        vc.erase(unique(vc.begin(), vc.end()), vc.end());
        LL ans = 0;
        for(auto& t : vc) {
            LL x = t.x, y = t.y;
            bool flag = true;
            for(int i = 3; i <= n; i++) {
                y = y * t.y;
                if(y > r) {
                    flag = false;
                    break;
                }
            }
            if(!flag) continue;
            for(int i = 3; i <= n; i++) {
                x = x * t.x;
                if(x > 10000000LL * y) {
                    flag = false;
                    break;
                }
            }
            if(!flag) continue;

            int Ly = ((l - 1) / y) + 1, Ry = r / y;
            int Lx = ((l - 1) / x) + 1, Rx = r / x;
            if(Ly > Ry) continue;
            if(Lx > Rx) continue;
            if(Lx > Ry) continue;
            if(Rx < Ly) continue;
            Lx = max(Lx, Ly);
            Rx = min(Rx, Ry);
            ans += Rx - Lx + 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

/*
3 1 10000000
*/

 

posted @ 2019-03-29 00:03  NotNight  阅读(152)  评论(0编辑  收藏  举报