Codeforces 758F 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 ", r - l + 1); } else if(n == 2) { printf("%lld ", 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 ", ans); } return 0; } /* 3 1 10000000 */