zoukankan      html  css  js  c++  java
  • Atcoder abc110D.Factorization【隔板法】

    题目链接
    思路
    隔板法:将(n)个球放入(m)个盒子中,盒子可以为空,那么方案数为(C_{n+m-1}^{m-1})
    证明:用隔板法相当于在n个球中间插入(m-1)块板子,但是有可能会出现连续空着的盒子出现,例如“xx|xx|||xx”的情况(用x代表球,|代表插入的隔板)。那么最好的办法就是增加(m)个球,假装每个盒子内至少有一个球。假设某个盒子内球的数量为(x)个,那么盒子内实际的球数为(x-1)个。相当于将(n+m)个球分割为(m)个空间,每个空间内至少要有一个球。所以方案数即为(C_{n+m-1}^{m-1}).

    对于本题思路即是对于(m)进行质因子分解,(m=p_1^{a_1}*p_2^{a_2}*p_3^{a_3}*...),每一个质因子都是相对独立的,那么对于一个质因子就变成独立的小问题:将(a_i)个球放入(n)个盒子的方案数,总方案数就是将每一个质因子的方案数乘起来即可。
    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<int, int> PII;
    const int N = 2e5 + 10;
    #define gcd __gcd
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    LL f[N], inv[N];
    vector<int> nums;
    bool st[N];
    
    LL kpow(LL a, LL n) {
    	LL res = 1;
    	while(n) {
    		if(n & 1) res = res * a % mod;
    		n >>= 1;
    		a = a * a % mod;
    	}
    	return res;
    }
    
    void init() {
    	int n = 2e5;
    	f[0] = f[1] = 1;
    	inv[0] = inv[1] = kpow(1, mod - 2);
    	for(int i = 2; i <= n; i++) {
    		f[i] = 1LL * f[i - 1] * i % mod;
    		inv[i] = 1LL * inv[i - 1] * kpow(i, mod - 2) % mod;
    		if(!st[i]) nums.push_back(i);
    		for(int j = 0; j < nums.size() && i <= n / nums[j]; j++) {
    			st[i * nums[j]] = true;
    			if(i % nums[j] == 0) break;
    		}
    	}
    }
    
    LL C(LL a, LL b) {
    	return f[a] * inv[b] % mod * inv[a - b] % mod;
    }
    
    void solve() {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	LL res = 1;
    	for(int i = 0; i < nums.size() && nums[i] <= m / nums[i]; i++) {
    		int cnt = 0;
    		while(m % nums[i] == 0) {
    			cnt++;
    			m /= nums[i];
    		}
    		if(cnt > 0) {
    			res = 1LL * res * C(n + cnt - 1, n - 1) % mod;
    		}
    	}
    	if(m > 1) {
    		res = 1LL * res * C(n, n - 1) % mod;
    	}
    	printf("%lld
    ", res);
    }
    
    int main() {
    	init();
    	// freopen("in.txt", "r", stdin);
    	// int t; cin >> t; while(t--)
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    算法-在字符串中删除特定的字符或字符串
    Linux 下的7种文件类型
    TCP/IP协议、三次握手、四次挥手
    8、VUE自定义组件
    7、VUE事件
    6、VUE指令
    Redis高级功能-1、高并发基本概述
    5、插值
    4、VUE生命周期
    3、Vue实例的属性
  • 原文地址:https://www.cnblogs.com/ZX-GO/p/14742289.html
Copyright © 2011-2022 走看看