zoukankan      html  css  js  c++  java
  • [HAOI2007]反素数ant

    1053: [HAOI2007]反素数ant

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1907  Solved: 1069
    [Submit][Status][Discuss]

    Description

     

    对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
    如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
    现在给定一个数N,你能求出不超过N的最大的反质数么?

    Input

    一个数N(1<=N<=2,000,000,000)。

    Output

    不超过N的最大的反质数。

    Sample Input

    1000

    Sample Output

    840

    HINT

     

    Source

                      [Submit][Status][Discuss]
    【题解】
    首先,可以用组合数学证得,如果一个数n=a1x1×a2x2×……×akxk
    那么,设函数ex-phi(n)表示n的约数的个数
    可推导出ex-phi(n)=(x1+1)(x2+1)...(xk+1) ................(这只是个公式,我并不会证明)
    上面的结论称为定理1
    ===========================================
    通过计算可以得出当N在2000000000以内时,最多只有10个素因子
    证明:2*3*5*7*11*13*17*19*23*29≈60e>20e
    上面的结论称为定理2
    ===========================================
    小素因子多一定比大素因子多要优秀
    小素因子多那么总因子多,ex-phi(n)肯定比大素因子多的大。
    上面的结论称为定理3
    ===========================================
    然而推出这些神奇的结论后,我们发现——
        我们维护素因子从小到大数量的单调递减性即可。
     
    代码不太好懂,,,,我加了不少注释
     1 #include<bits/stdc++.h> 
     2 using namespace std;
     3 long long prime[100]={0,2,3,5,7,11,13,17,19,23,29,31,37};
     4 long long ans,num,n;
     5 //num=目前约数最多的数中最小的数(语言能力有限...)  ans=目前约数最多的约数的个数 
     6 inline void dfs(int now,   long long product,   long long cs,   long long lastcs,    long long res)
     7 //           当前质数下标          当前乘积     当前数出现次数    上一个数出现次数         约数个数 
     8 {
     9     if(ans==res*(cs+1)&&product<num)//当前乘积的这个数是约数个数已经等于ans,且比num小 
    10         num=product;// 更新答案 
    11     if(res*(cs+1)>ans){//这个没的说,肯定更新啦 
    12         ans=res*(cs+1);
    13         num=product;
    14     }
    15     if(cs+1<=lastcs&&product*prime[now]<=n)//每个质数的指数保证单调不上升且不超过n 
    16         dfs(now,product*prime[now],cs+1,lastcs,res);
    17 
    18     for(int i=now+1;i<=10;i++)//在数据范围内用到的质数不会超过10 
    19         if(product*prime[i]<=n)//注意不能超过n 
    20             dfs(i,product*prime[i],1,cs,res*(cs+1));
    21 }
    22 
    23 inline void go()
    24 {
    25     dfs(1,1,0,100,1);
    26     printf("%lld
    ",num);
    27 }
    28 
    29 int main()
    30 {
    31     scanf("%lld",&n);
    32     go();
    33     return 0;
    34 }
  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4687940.html
Copyright © 2011-2022 走看看