[CQOI2015]选数
/*
Author : lifehappy
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10, mod = 1e9 + 7;
int prime[N], mu[N], cnt;
bool st[N];
ll quick_pow(ll a, int n) {
ll ans = 1;
while(n) {
if(n & 1) ans = ans * a % mod;
a = a * a % mod;
n >>= 1;
}
return ans;
}
void init() {
mu[1] = 1;
for(int i = 2; i < N; i++) {
if(!st[i]) {
prime[++cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt && 1ll * i * prime[j] < N; j++) {
st[i * prime[j]] = 1;
if(i % prime[j] == 0) {
break;
}
mu[i * prime[j]] = -mu[i];
}
}
for(int i = 1; i < N; i++) {
mu[i] = (mu[i] + mu[i - 1] + mod) % mod;
}
}
unordered_map<int, int> ans_s;
int Djs(int n) {
if(n < N) return mu[n];
if(ans_s.count(n)) return ans_s[n];
int ans = 1;
for(int l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
ans = (ans - 1ll * (r - l + 1) * Djs(n / l) % mod + mod) % mod;
}
return ans_s[n] = ans;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
init();
int N, K, L, H;
scanf("%d %d %d %d", &N, &K, &L, &H);
L = (L - 1) / K, H = H / K;
//提前对 L 进行向下取整,所以在后面就可以不用进行ceil,然后相减加 1 操作了
ll ans = 0;
for(int l = 1, r; l <= H; l = r + 1) {
r = L / l ? min(L / (L / l), H / (H / l)) : H / (H / l);
ans = (ans + (Djs(r) - Djs(l - 1)) * quick_pow(H / l - L / l, N) % mod + mod) % mod;
}
printf("%lld\n", ans);
return 0;
} 
京公网安备 11010502036488号