• 【搜索】【约数个数定理】[HAOI2007]反素数ant


    对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
    如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。


    所以,n以内的反质数即为不超过n的约数个数最多的数。

    怎样计算约数个数?

    约数个数定理:
    对于一个大于1正整数n可以分解质因数:n=p1^a1*p2^a2*p3^a3*…*pk^ak,
    则n的正约数的个数就是(a1+1)(a2+1)(a3+1)…(ak+1) .
    其中a1、a2、a3…ak是p1、p2、p3,…pk的指数。
     
    所以,只需枚举一个数的所有质因数就行。
     
    最多用到的 不同的 质因数 有多少呢?
     
    ∵2*3*5*7*11*13*17*19*23*29>2000000000
     
    ∴最多只用用到这么多不同的质因数。
     
    搜索即可。
     
    加两个剪枝:
    ①从小到大枚举质因数,不要让 顺序不同的 算作不同的方案。
     
    ②小的因数的指数必然大于大的因数的指数,
    ∵<1>约数个数相同时,小的数更优。
    <2>大的数与小的数有相同的因数个数时,根据定义,大的数压根不是反质数了。

    Code:
     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 const int prime[]={0,2,3,5,7,11,13,17,19,23,29};
     5 int n,Time[11],sum;
     6 long long ans;
     7 int Calc()
     8 {
     9     int res=1;
    10     for(int i=1;i<=10;i++)
    11       res*=(Time[i]+1);
    12     return res;
    13 }
    14 void dfs(long long now,int last)
    15 {
    16     if(now>n)
    17       return;
    18     int tmp=Calc();
    19     if(sum<tmp||(sum==tmp&&now<ans)){sum=tmp;ans=now;}
    20     for(int i=1;i<=10;i++)
    21       if(Time[i]<Time[i-1]&&i>=last)
    22         {
    23             Time[i]++;
    24             dfs(now*prime[i],i);
    25             Time[i]--;
    26         }
    27 }
    28 int main()
    29 {
    30     scanf("%d",&n);
    31     Time[0]=2147483647;
    32     dfs(1,0);
    33     cout<<ans<<endl;
    34     return 0;
    35 }
    ——The Solution By AutSky_JadeK From UESTC 转载请注明出处:http://www.cnblogs.com/autsky-jadek/
  • 相关阅读:
    前端思想实现:面向UI编程_____前端框架设计开发
    使用单体模式设计原生js插件
    QQ空间首页背景图片淡出解析与不足完善
    网页字体设置
    Asp.net MVC Session过期异常的处理
    日本设计的七个原则
    断开所有远程连接(sql server)
    Ubuntu1404+Django1.9+Apache2.4部署配置2配置文件设置
    Linux系统查找文件find命令使用(不断更新)
    ubuntu1404下Apache2.4错误日志error.log路径位置
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/3959469.html
Copyright © 2020-2023  润新知