zoukankan      html  css  js  c++  java
  • [JZOJ 5791] 阶乘

    题意:求一个最小的\(m\),保证\(\prod a[i] * x = m!\)
    思路:
    考虑\(m!\)里面有多少个东西??
    \(m\)个。
    且是一个排列。
    那么求一个最小的\(m\)使得前面的式子成立?
    我们考虑如何统计\(m!\)中每个因子出现的次数?
    \(m/(x^k)!\)
    那么就好办了,我们对于序列中的每一个数直接分解质因数,统计每个数出现的次数。
    因为\(m!\)中出现的次数不可能比序列中小,且如果\(m!\)中包含了所有的\(x\)就等于包含了序列。
    那么直接二分判断数值即可。
    时间复杂度:\(O(n \sum \sqrt{a[i]} + log INF)\)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    const int INF = 1e8;
    int prime[maxn];
    int a[maxn];
    int Mx;
    int n;
    int ans;
    inline bool ok(int x) {
    	if(x < Mx) return 0;
    	for(int i = 2;i <= x && i <= Mx; ++i) {
    		if(!prime[i]) continue;
    		int sum = 0;
    		int tmp = x;
    		while(tmp) {
    			sum += tmp/i;
    			tmp /= i;
    		}
    		if(sum < prime[i]) {
    			return 0;
    		}
    	}
    	return 1;
    }
    int main () {
    	freopen("factorial.in","r",stdin);
    	freopen("factorial.out","w",stdout);
    	scanf("%d",&n);
    	for(int i = 1;i <= n; ++i) {
    		scanf("%d",&a[i]);
    		for(int j = 2;j * j<= (a[i]); ++j) {
    			while(a[i] % j == 0) {
    				prime[j] ++;
    				a[i] /= j;
    				Mx = max(Mx,j);
    			}
    		}
    		if(a[i] > 1) {
    			prime[a[i]] ++;
    			Mx = max(Mx,a[i]);
    		}
    	}
    	
    	int l = 0,r = INF;
    	while(l <= r) {
    		//cout<<l<<' '<<r<<endl;
    		int mid = (l + r) >> 1;
    		if(ok(mid)) {
    			r = mid - 1,ans = mid;
    		}
    		else l = mid + 1;
    		//cout<<ans<<endl;
    	}
    	printf("%d\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    【转】IOS开发:[1]Xcode5界面入门
    【转】Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得
    特征选择
    EM算法
    算法之美--3.2.3 KMP算法
    算法之美--3.2.2 MP算法
    图像质量评价方法PSNR+SSIM&&评估指标SROCC,PLCC
    C/C++二进制读写png文件
    大津法---OTSU算法
    一些优秀的面试笔试总结
  • 原文地址:https://www.cnblogs.com/akoasm/p/9588844.html
Copyright © 2011-2022 走看看