zoukankan      html  css  js  c++  java
  • 【YBTOJ】【DFS】最多约数

    最多约数

    给定一个正整数 (n) ,对于所有不超过 (n) 的正整数,找到包含约数最多的一个数。如果有多个这样的数,那么回答最小的那个。

    (nleq 10^{16})

    题解

    首先有一个结论:

    • 若正整数 (N) 被唯一质因数分解为 (N=p_1^{c_1}p_2^{c_2}dots p_m^{c_m}) ,且满足 (p_1<p_2<dots<p_m)
    • 则: (N) 的正约数个数为 (prodlimits_{i=1}^m (c_i+1)) .

    应用这个结论,我们可以直接枚举因数的 (i) 次方,进行搜索优化。

    另外有一个剪枝:

    • 题目要求数最小,则可知满足时, (c_1ge c_2gecdots c_m) 必定成立。
    • (i) 加上限制即可。

    代码

    #pragma GCC optimize("Ofast")
    #include <bits/stdc++.h>
    #define fo(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    const int INF = 0x3f3f3f3f,N = 1e6+5;
    typedef long long ll;
    typedef unsigned long long ull;
    inline ll read(){
    	ll ret=0;char ch=' ',c=getchar();
    	while(!(c>='0'&&c<='9'))ch=c,c=getchar();
    	while(c>='0'&&c<='9')ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
    	return ch=='-'?-ret:ret;
    }
    ll n,m;
    ll pri[N]; bool vis[N];
    void Prime(){
    	for(int i = 2 ; i <= 1e6 ; i ++){
    		if(!vis[i]) pri[++m] = i;
    		for(int j = 1 ; j <= m && i*pri[j] <= 1e6 ; j ++){
    			vis[i*pri[j]] = 1;
    			if(!(i%pri[j])) break;
    		}
    	}
    }
    ll anS,anC;
    void dfs(int cur,int lim,ll s,ll c){
    	if(c > anC || (c == anC && s < anS)) anS = s , anC = c;
    	if(cur > m || s * pri[cur] > n) return;
    	s *= pri[cur];
    	for(int i = 1 ; i <= lim && s <= n ; i ++ , s *= pri[cur])
    		dfs(cur+1,i,s,c*(i+1));
    }
    signed main(){
    	n = read();
    	Prime();
    	dfs(1,53,1,1);
    	printf("%lld",anS);
    } 
    
  • 相关阅读:
    centos 7 安装ntp服务器
    centos 7编译安装nodejs 6.1
    修改IKAnalyzer配置
    Elasticsearch5.5.0安装head插件
    搭建ELASTICSEARCH实现中文分词搜索功能
    0426HTML基础:标签
    事件事件流
    纯css设置各行变色
    dom操作之元素的增删复制
    dom操作
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15317953.html
Copyright © 2011-2022 走看看