Description

粗题⼈症重承诺此题不考你没学过的算法

给你⼀个区间[L,R]

需要选择N个数,这N个数都在这个区间范围内

那么我们知道⼀共有[R-L+1]^N种选法

假如我们想要这N个数的最⼤公约数恰好是K

请问⼀共有多少种选法,输出答案对1e9+7取模

Input

 多组测试数据 对于每组数据,输⼊⼀⾏包含4个整数N,K,L,R(1<=N,K,L<=10^9,L<=R<=10^9)

(0<=R-L<=10^5)

Output

 对于每组数据输出⼀个整数

Sample Input

2 2 2 4
2 100 2 4
1 5 5 5
73824 17347 9293482 9313482
222 222 222 22222

Sample Output

3
0
1
0
339886855

HINT

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <cstdio> 
#include <cstring> 
#include <cstdlib> 
#include <cmath> 
#include <ctime> 
#include <algorithm> 
#include <vector> 
#include <queue> 
#include <deque> 
#include <stack> 
#include <set> 
#include <map> 
#include <complex> 
#include <bitset> 
#include <iomanip> 
#include <utility> 

using namespace std; 

typedef long long LL; 
typedef pair<int,int> pii; 
typedef complex<double> point; 

const int mod = 1000000007; 

int f[200000]; 

int POW (int base, int p){ 
  int ret = 1, cur = base; 
  while (p){ 
    if (p & 1) ret = (LL)ret * cur % mod; 
    p>>=1; 
    cur = (LL)cur * cur % mod; 
  } 
  return ret; 
} 

struct RandomGCD{ 
  int countTuples(int N, int K, int lo, int hi){ 
      memset(f, 0, sizeof(f));
    lo = (lo+K-1)/K, hi = hi/K;  
    if (lo > hi) 
      return 0; 
    for (int i=100000; i>=1; i--){ 
      int L = (lo + i-1) / i; 
      int H = hi / i; 
      if (L <= H){ 
        f[i] = POW(H-L+1, N);  
        f[i]-= (H-L+1); 
        if (f[i] < 0) f[i]+= mod; 
        for (int j=i*2; j<=100000; j+=i){ 
          f[i]-=f[j]; 
          if (f[i]<0) f[i]+= mod; 
        } 
      } 
    } 
    if (lo == 1) 
      f[1] = (f[1] + 1) % mod; 
    return f[1]; 
  }   
};

int main() {
    RandomGCD test;
    int N, K, L, R;
    while (cin >> N >> K >> L >> R) {
        cout << test.countTuples(N, K, L, R) << endl;
    }
    return 0;
}