n == 1的时候答案为区间长度, n == 2的时候每两个数字都可能成为答案,
我们只需要考虑 n == 3的情况, 我们可以枚举公差, 其分子分母都在sqrt(1e7)以内,
然后暴力枚举就好啦。
#include#define LL long long#define fi first#define se second#define mk make_pair#define PLL pair #define PLI pair #define PII pair #define SZ(x) ((int)x.size())#define ull unsigned long longusing 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 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*/