Codeforce893E Counting Arrays

题意:输入q,q个询问,每次输入x,y,问有多少种方案使得y个数相乘等于x

题解:一开始想用整数划分一样dp,发现数太大。。。后来发现这其实就是组合数学中的一个模型,小球放盒子模型的变形,把x进行分解,每一个数就是小球放入y个盒子,x个球放入y个盒子,小球都相同的话答案就是c(x+y-1, x)但是有部分相同就是一个分步的过程,答案就是c(a1+y-1, a1)+c(a2+y-1, a2)....

#include <bits/stdc++.h>
#define maxn 200010
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll prime[100], num, inv[maxn], p[maxn];
ll exd_mod(ll a,ll b){
    ll ans = 1;
    while(b){
        if(b&1) ans = ans*a%mod;
        a = a*a%mod;
        b>>=1;
    }
    return ans;
}
ll c(ll a, ll b){
    ll ans=1, i;
    for(i=1;i<=b;i++)ans=ans*(a-i+1)%mod,ans=ans*inv[i]%mod;
    return ans;
}
int main(){
    ll q, x, y, ans;
    scanf("%lld", &q);
    p[0] = 1;
    for(ll i=1;i<100;i++) inv[i] = exd_mod(i, mod-2);
    while(q--){
        num = ans = 1;memset(prime, 0, sizeof(prime));
        scanf("%lld%lld", &x, &y);
        for(ll i=2;i*i<=x;i++)
            if(x%i == 0){
                while(x%i == 0) x/=i,prime[num]++;num++;
            }
        if(x!=1) prime[num++] = 1;
        for(ll i=1;i<num;i++) ans = ans*c(y-1+prime[i], prime[i])%mod;
        ans = (ans*exd_mod(2, y-1))%mod;
        printf("%lld
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/7894386.html