反素数 Antiprime

反素数

题目描述

原题来自:POI 2001

如果一个大于等于 1 1 1 的正整数 n n n,满足所有小于 n n n 且大于等于 1 1 1 的所有正整数的约数个数都小于 n n n 的约数个数,则 n n n 是一个反素数。譬如: 1 , 2 , 4 , 6 , 12 , 24 1, 2, 4, 6, 12, 24 1,2,4,6,12,24,它们都是反素数。

请你计算不大于 n n n 的最大反素数。

输入

一行一个正整数 n n n

输出

只包含一个整数,即不大于 n n n 的最大反素数。

样例

1000
840

提示

数据范围与提示:

对于 10% 的数据, 1 ≤ n ≤ 1 0 3 1≤n≤10^3 1n103

对于 40% 的数据, 1 ≤ n ≤ 1 0 6 1≤n≤10^6 1n106

对于 100% 的数据, 1 ≤ n ≤ 2 × 1 0 9 1≤n≤2×10^9 1n2×109

来源

一本通在线评测

想法

image-20211227210457699

什么是反质数?

如果所有小于x的数i,数i的约数个数=g[i]
都有g[i]<g[x],则x是反素数。

1~n中最大的反素数等价于?

  • 求1~n中最大的反素数
    等价于:

  • 求1~n中约数最多的数中最小的数。

假设有2个约数最多的数x,y,g[x]=g[y]=10,
则更大的y因为x<y而g[x]!<g[y]而导致y不是反素数

首先,虽然n很大,但是反质数是一个很小的数。因为它要满足:

  1. 质因子次数单调递减。

  2. 质因子最大枚举到 28。

    2 × 3 × 5 × 7 × 11 × 13 × 17 × 19 × 23 × 29 > 6 × 1 0 9 > 2 × 1 0 9 2 \times 3 \times 5 \times 7 \times 11 \times 13 \times 17 \times 19 \times 23 \times 29>6 \times 10^{9}>2 \times 10^{9} 2×3×5×7×11×13×17×19×23×29>6×109>2×109

  3. 单个质因子的次数最多为 30。

    2 30 = 1 e 9 2^{30} = 1e9 230=1e9

采用上述三个性质,爆搜即可.找到哪个

#include<iostream>
using namespace std;
typedef long long LL;
int n;
int number;//number为约数个数最多的数的约数个数 == 最大反素数
int maxd;//maxd记录当前最大约数个数的数的约数个数 == 小于最大反素数位数个数 
int primes[9] = {2, 3, 5, 7, 11, 13, 17, 19, 23};

//u是当前枚举到第u个素数, last是前一个素数所枚举的次数
//爆搜到p了, s是p之前所有约数个数之和
void dfs(int u,int last,int p,int s)
{//如果当前约数个数>最大约数个数 || 当前约数个数==最大约数个数且 当前数更小
    if(s>maxd||s==maxd && p<number)
    {
        maxd=s;
        //更新最大约数为s,约数最多的数中最小的数p
        number = p;
    }
    if(u==9)return;//搜完了质数了
    //枚举当前质数可用的次数
    for(int i =1;i<=last;i++)
    {
        if((LL)p*primes[u]>n)break;
        p*=primes[u];
        //s*(i+1) 是约数个数的公式 
        dfs(u+1,i,p,s*(i+1));
    }
}

int main(){
	cin >> n;
	dfs(0,30,1,1);
	cout << number << endl;
	return 0;	
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值