題目鏈接:https://codeforc.es/problemset/problem/893/E
題目大意:有次詢問,每次給定,問滿足序列長度爲,且的序列數目,序列可爲負。
思路:要計算滿足條件的序列數目,首先想到的是將素因數分解,然後對於每次素因子,統計其出現的次數,要怎麼把這個數分成份呢,我們就想到了隔板法,類似於將個小球放進個盒子中,可以放空。
那麼對於來說,組合的種類數就是。
然後題目要求可以爲負數,但是,所以負數只能出現偶數次,即對於個數來說,負數的種類數就是。
AC代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
const int mod=1e9+7;
typedef long long ll;
ll qpow(ll x,ll y){
ll ans=1;
while(y>0){
if(y&1){
ans=ans*x%mod;
}
y>>=1;
x=x*x%mod;
}
return ans;
}
ll f[maxn];
ll inv[maxn];
void calf()
{
f[0]=1;
for(int i=1;i<maxn;i++){
f[i]=(f[i-1]*i)%mod;
}
inv[maxn-1]=qpow(f[maxn-1],mod-2);
for(int i=maxn-2;~i;i--){
inv[i]=inv[i+1]*(i+1)%mod;
}
}
ll C(int n,int m){
if(n<m||m<0){
return 0;
}
return f[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
int q;
int x,y;
int cnt;
calf();
scanf("%d",&q);
while(q--){
scanf("%d%d",&x,&y);
ll ans=1;
for(int i=2;i*i<=x;i++){
cnt=0;
if(x%i==0){
while(x%i==0){
x/=i;
cnt++;
}
ans=ans*C(cnt+y-1,y-1)%mod;
}
}
if(x>1){
ans=ans*y%mod;
}
ans=ans*qpow(2,y-1)%mod;
printf("%lld\n",ans);
}
return 0;
}
隔板法參考:https://blog.csdn.net/qq_39942341/article/details/80246780