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;
    }
    
  • 相关阅读:
    主机访问虚拟机网络服务失败
    关于接收者为指针的方法
    slice的部分说明
    ES基础知识
    静态语言和动态语言
    数据库设计三大范式
    SparkSQL小例子
    spark小例子
    spark 分析作者发布文章的总阅读量
    spark和hadoop差异
  • 原文地址:https://www.cnblogs.com/akoasm/p/9588844.html
Copyright © 2011-2022 走看看