问题 K: Factorization(隔板法+组合数学+线性求逆元)

问题 K: Factorization(隔板法+组合数学+线性求逆元)

题目描述

You are given positive integers N and M.
How many sequences a of length N consisting of positive integers satisfy a1×a2×…×aN=M? Find the count modulo 10 9+7.
Here, two sequences a’ and a” are considered different when there exists some i such that a’ i≠a” i.Constraints
·All values in input are integers.
·1≤N≤10 5
·1≤M≤10 9

输入

Input is given from Standard Input in the following format:
N M

输出

Print the number of the sequences consisting of positive integers that satisfy the condition, modulo 10 9+7.

样例输入 Copy

2 6

样例输出 Copy

4

提示

Four sequences satisfy the condition: {a1,a2}={1,6},{2,3},{3,2} and {6,1}.
思路:质因数分解,然后每个素数因子个数,设为x,转化为把x个相同的放进n个位置,开始写的n^x,但是wa,后来写的隔板法。
C(n+x-1,n-1)。
为啥不是n^x,因为元素相同,不同方案取决于每个盒子多少个球。又隔板法不能有空元素,但题目可以。所以我们添加三块隔板,答案为上。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
 
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
#define ms(s) memset(s, 0, sizeof(s))
 
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
typedef unordered_map<int,int> un_map;
template<class T>
inline void read (T &x) {
    x = 0;
    int sign = 1;
    char c = getchar ();
    while (c < '0' || c > '9') {
        if ( c == '-' ) sign = - 1;
        c = getchar ();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar ();
    }
    x = x * sign;
}
 
const int maxn = 1e6+10;
const int inf = 0x3f3f3f3f;
const ll INF = ll(1e18);
const int mod = 1e9+7;
const double PI = acos(-1);
#define LOCAL
 
ll n,m;
ll f[maxn],inv[maxn];
 
 
void init() {
    inv[0]=1;
    inv[1]=1;
    f[1]=1;
    f[0]=1;
 
    rep(i,2,maxn-5) {
        f[i]=f[i-1]*i%mod;
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    }
 
    rep(i,2,maxn-5) {
        inv[i]=inv[i]*inv[i-1]%mod;
    }
}
 
ll C(ll p,ll q) {
    return f[p]*inv[q]%mod*inv[p-q]%mod;
}
 
void solve() {
    ll ans = 1;
    for(ll i=2;i*i<=m;i++) {
        if(m%i==0) {
            ll cnt = 0;
            while(m%i==0) {
                m/=i;
                cnt++;
            }
            ans=(ans*C(n+cnt-1,n-1)%mod+mod)%mod;
        }
    }
    if(m!=1) ans=ans*n%mod;
    printf("%lld\n",ans);
}
 
int main(int argc, char * argv[])
{
    //freopen("/home/yesky/桌面/date.in", "r", stdin);
    //freopen("/home/yesky/桌面/date.out", "w", stdout);
    init();
    while(~scanf("%lld%lld",&n,&m)) {
        solve();
    }
    return 0;
}
发布了259 篇原创文章 · 获赞 2 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/dy416524/article/details/105733995
今日推荐