P1463 [POI2001][HAOI2007] 反素数——解题报告

13 篇文章 0 订阅
5 篇文章 0 订阅

一、题目链接

P1463 [POI2001][HAOI2007] 反素数

二、题目大意

设函数 f ( x ) f(x) f(x)表示 x x x的约数个数。对于一个正整数 x x x,若满足任意 0 < i < x 0<i<x 0<i<x,都有 f ( x ) f(x) f(x)大于 f ( i ) f(i) f(i)。那么称 x x x为反质数。现给定数 N N N,找到 1 ∼ N 1 \sim N 1N中最大的反质数。

数据范围: 1 ≤ N ≤ 2 × 1 0 9 1 \leq N \leq 2 \times 10^9 1N2×109

三、题目分析

首先, 1 ∼ N 1 \sim N 1N的最大反质数一定是 1 ∼ N 1 \sim N 1N中约数个数最多的数中最小的一个。下面给出证明:

  • 设这个数为 x x x,因为 f ( x ) f(x) f(x)最大是函数 g g g的最大值,且 x x x是最小的那一个,所以小于 x x x的数的 f ( i ) < f ( x ) f(i)<f(x) f(i)<f(x)成立,所以 x x x为反质数。
  • 因为 f ( x ) f(x) f(x)最大是函数g的最大值,且 x x x是最小的那一个,所以大于 x x x的数的 f ( i ) ≤ f ( x ) f(i) \leq f(x) f(i)f(x)成立,所以大于 x x x的所有数一定不是反质数。

x x x为反质数的必要条件是: x x x分解质因数后可以写成 2 c 1 × 3 c 2 × 5 c 3 × 7 c 4 × 1 1 c 5 × 1 3 c 6 × 1 7 c 7 × 1 9 c 8 × 2 3 c 9 × 2 9 c 10 2^{c_1} \times 3^{c_2} \times 5^{c_3} \times 7^{c_4} \times 11^{c_5} \times 13^{c_6} \times 17^{c_7} \times 19^{c_8} \times 23^{c_9} \times 29^{c_{10}} 2c1×3c2×5c3×7c4×11c5×13c6×17c7×19c8×23c9×29c10。并且 c 1 ≥ c 2 ≥ c 3 ≥ c 4 ≥ c 5 ≥ c 6 ≥ c 7 ≥ c 8 ≥ c 9 ≥ c 10 c_1 \geq c_2 \geq c_3 \geq c_4 \geq c_5 \geq c_6 \geq c_7 \geq c_8 \geq c_9 \geq c_{10} c1c2c3c4c5c6c7c8c9c10。下面给出证明:

  • 反证法:若存在质因数分解中有一项 p k ( p > 29 ) p^k(p>29) pk(p>29),则必定有不超过 29 29 29的质因子 p ′ p' p不能整除 x x x。显然 x / p k × p ′ k x/p^k \times p'^k x/pk×pk的约数个数和 x x x相同,但 x / p k × p ′ k < x x/p^k \times p'^k<x x/pk×pk<x所以根据 1 1 1,发现与定义矛盾,所以质因数一定小于 29 29 29
  • 反证法:若 x x x的质因数不是连续的,同上用 p ′ k ′ p'^{k'} pk代替最大的质因数 p p p的项 p k p^k pk得到更小的值,与定义矛盾。
  • 反证法:若 x x x的质因数的指数不单调递减,则一定有相邻两项 p 1 a × p 2 b p_1^a \times p_2^b p1a×p2b满足 p 1 < p 2 p_1<p_2 p1<p2,且 a > b a>b a>b。而同上替换为 p 1 b × p 2 a p_1^b \times p_2^a p1b×p2a,一定更小,且约数数目相同。与定义矛盾。

综上所述,我们只需要 D F S DFS DFS搜索答案即可,因为实际上的搜索范围很小,所以并不会超时。

四、正解程序

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll maxn=100010; 
ll prime[maxn/10],count1=0,n;
bool vis[maxn];
void oula()
{
	memset(vis,false,sizeof(vis));
	for(ll i=2;i<=maxn-10;i++)
	{
		if(!vis[i])
			prime[++count1]=i;
		for(ll j=1;j<=count1 && prime[j]*i<=maxn-10;j++)
		{
			vis[prime[j]*i]=true;
			if(i%prime[j]==0)
				break;
		}
	}
}
ll ans=0x7fffffff,Max=-1;
void dfs(ll k,ll val,ll last,ll times)
{
    if(k>16)
        return;
    if(Max<times)
    {
        Max=times;
        ans=val;
    }
    else if(Max==times)
        ans=min(val,ans);
    for(ll i=1;i<=last;i++)
    {
        ll temp=val*prime[k];
        if(temp>n)
            return;
        dfs(k+1,temp,i,times*(i+1));
        val*=prime[k];
    }
}
int main()
{
    oula();
    scanf("%lld",&n);
    dfs(1,1,100,1);
    printf("%lld\n",ans);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值