传送门
大力Lucas定理。
首先将N,M转化为P进制数。
然后发现只要有一位满足mi>ni就是0
发现不太好算。
转化为C(n,m)!=0的计算。
发现所有mi必须小于等于ni。
方案数=
Πni+1
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define mo 1000000000
using namespace std;
struct bignum{
ll a[20];
bignum(int x=0){
memset(a,0,sizeof(a));
if (!x) return;
a[0]=1; a[1]=x;
}
friend bignum operator +(bignum a,bignum b){
bignum c;
c.a[0]=max(a.a[0],b.a[0]);
for (int i=1;i<=c.a[0];i++) c.a[i]=a.a[i]+b.a[i];
for (int i=1;i<=c.a[0];i++){
c.a[i+1]+=c.a[i]/mo;
c.a[i]%=mo;
}
if (c.a[c.a[0]+1]) c.a[0]++;
return c;
}
friend bignum operator -(bignum a,bignum b){
bignum c;
c.a[0]=max(a.a[0],b.a[0]);
for (int i=1;i<=c.a[0];i++) c.a[i]=a.a[i]-b.a[i];
for (int i=1;i<=c.a[0];i++)
if (c.a[i]<0){
c.a[i]+=mo;
c.a[i+1]--;
}
while (c.a[0]&&!c.a[c.a[0]]) c.a[0]--;
return c;
}
friend bignum operator *(bignum a,int b){
bignum c; c.a[0]=a.a[0];
for (int i=1;i<=c.a[0];i++) c.a[i]=a.a[i]*b;
for (int i=1;i<=c.a[0];i++){
c.a[i+1]+=c.a[i]/mo;
c.a[i]%=mo;
}
c.a[0]++;
while (c.a[0]&&!c.a[c.a[0]]) c.a[0]--;
return c;
}
friend bignum operator /(bignum a,int b){
bignum c; c.a[0]=a.a[0];
ll x=0;
for (int i=a.a[0];i;i--){
x=x*mo+a.a[i];
c.a[i]=x/b;
x%=b;
}
while (c.a[0]&&!c.a[c.a[0]]) c.a[0]--;
return c;
}
friend int operator %(bignum a,int b){
ll x=0;
for (int i=a.a[0];i;i--)
x=(x*mo+a.a[i])%b;
return x;
}
void print(){
printf("%lld",a[a[0]]);
for (int i=a[0]-1;i>0;i--)
printf("%09lld",a[i]);
puts("");
}
}a,b;
char s[105];
int M,T,q[505],P[11],t[105];
inline void solve(){
scanf("%s%d",s+1,&M);
int len=strlen(s+1);
for (int i=1;i<=len;i++) t[i]=s[len-i+1]-'0';
a=bignum(0);
for (int i=1;i<=len;i++)
a.a[(i-1)/9+1]+=t[i]*P[(i-1)%9+1];
a.a[0]=(len-1)/9+1; b=a;
int tot=0;
while (a.a[0]){
q[++tot]=a%M;
a=a/M;
}
a=bignum(1);
for (int i=1;i<=tot;i++) a=a*(q[i]+1);
a=b+bignum(1)-a;
a.print();
}
int main(){
scanf("%d",&T);
P[1]=1;
for (int i=2;i<=9;i++) P[i]=P[i-1]*10;
while (T--) solve();
}