topic
The number of combinations C(n,m) represents the number of solutions for selecting m items from n items. For example, choosing two items from three items (1, 2, 3) can have (
1,2), (1,3), (2,3) three selection methods. According to the definition of the number of combinations, we can give the general formula for calculating the number of combinations C(n,m):
C(n,m)=n!/m!*(n?m)!
where n!=1×2× ?×n. (Additionally, when n=0, n!=1)
Shallot wants to know how many pairs (i,m) for all 0≤i≤n,0≤j≤min(i,m) given n,m, and k i,j) satisfy that C(i,j) is a multiple of k.
input format
The first line has two integers t, k, where t represents the total number of sets of test data at the test point, see the meaning of k.
In the next t lines, each line contains two integers n and m, where the meaning of n and m can be seen.
output format
t lines, each line is an integer representing all 0≤i≤n, 0≤j≤min(i,m) how many pairs (i,j)) satisfy C(i,j) is a multiple of k
The answer is modulo 10^9+7.
input sample
3 23
23333333 23333333
233333333 233333333
2333333333 2333333333
Sample output
851883128
959557926
680723120
hint
1≤n, m≤10^18, 1≤t, k≤100, and k is a prime number
answer
According to the \(Lucas\) theorem, we know that under the prime number \(k\)
\[{n \choose m} \equiv \prod_{i = 1} {n \mod k^i \choose m \mod k^ i} \pmod k\]
Thus, the result is \(0\) if and only if there is a \(i\) such that \({n \mod k^i \choose m \mod k^i} \ equiv 0 \pmod k\)
A combined number is 0 in the sense of a modular prime number, if and only if \(n < m\)
a combined number is not 0 in the sense of a modular prime number, then it is \(n >= m\ )
Then we split \(n\) and \(m\) into \(k\) base numbers, we can set a dp:
\(f[i][0/1][0/1]\) Indicates the number of \(n >= m\) solutions before the \(i\) bit ( whether \(n\) reaches the upper bound) ( whether \(m\) reaches the upper bound) , that is, not \(0\ ) The number of plans can finally be subtracted from the total plan, and the transfer can be pushed by yourself
Be aware that multiplication may overflow, use fast multiplication
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
#define cls(s) memset(s,0,sizeof(s))
using namespace std;
const int maxn = 105,maxm = 100005,INF = 1000000000,P = 1e9 + 7;
LL n,m,f[maxn][2][2],a[maxn],b[maxn],ai,bi,N,K,v2;
LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1,a = a * a % P)
if (b & 1) ans = ans * a % P;
return ans;
}
void add(LL& a,LL b){
a += b;
if (a >= P) a -= P;
}
LL Mul(LL a,LL b){
LL re = 0;
for (; b; b >>= 1,a = (a + a) % P) if (b & 1) re = (re + a) % P;
return re;
}
LL S(LL x){return Mul(x,x + 1) * v2 % P;}
int main(){
int T; scanf("%d%lld",&T,&K); v2 = qpow(2,P - 2);
while (T--){
cls(a); cls(b); cls(f);
scanf("%lld%lld",&n,&m); ai = bi = 0;
LL ans = S(min(n,m) + 1);
ans = (ans + Mul(m + 1,max(n - m,0ll))) % P;
while (n) a[++ai] = n % K,n /= K;
while (m) b[++bi] = m % K,m /= K;
N = max(ai,bi);
f[N][1][1] = 1;
for (int i = N; i; i--){
//0 0
add(f[i - 1][0][0],S(K) * f[i][0][0] % P);
//0 1
add(f[i - 1][0][0] ,(S(b[i]) + b[i] * (K - b[i]) % P) % P * f[i][0][1] % P);
add(f[i - 1][0][1],(K - b[i]) * f[i][0][1] % P);
//1 0
add(f[i - 1][0][0],S(a[i]) * f[i][1][0] % P);
add(f[i - 1][1][0],(a[i] + 1) * f[i][1][0] % P);
//1 1
if (a[i] >= b[i]){
add(f[i - 1][0][0],(S(b[i]) + b[i] * ((a[i] - b[i] + P) % P) % P) % P * f[i][1][1] % P);
add(f[i - 1][1][0],b[i] * f[i][1][1] % P);
add(f[i - 1][0][1],(a[i] - b[i] + P) % P * f[i][1][1] % P);
add(f[i - 1][1][1],f[i][1][1]);
}
else {
add(f[i - 1][0][0],S(a[i]) * f[i][1][1] % P);
add(f[i - 1][1][0],(a[i] + 1) % P * f[i][1][1] % P);
}
}
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
ans = (ans - f[0][i][j] + P) % P;
printf("%lld\n",(ans % P + P) % P);
}
return 0;
}