bzoj 1053: [HAOI2007]反素数ant (数论)

1053: [HAOI2007]反素数ant

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 2742   Solved: 1552
[ 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]

题解:这道题如果直接枚举求1-n之间每个数的个数的话,由于数据范围较大,时间复杂度会非常高。那么这里用到里一个数学知识,将一个数质因数分解,可分解为2^x * 3^y * 5^z.....,而要求n的约数个数的话,就通过乘法原理s=(x+1)*(y+1)*(z+1)....;至于为什么我们可以这么想这个数的每一个约数都是由它的质因数想成得到的,而在组合时每一个质因数的个数都有该质因数个数+1 种选择,所以一共可以组合出(x+1)*(y+1)*(z+1)....个数。至于为什么只需要最多10个数就可以了,是因为前十个质数相乘,乘积已经超过了数据范围。要解决这个问题还有关键的一点是需要知道:一个反质数的质因子必然是从2开始连续的质数。就好比2*3*5与2*3*7的因数个数相同,但是2*3*7比2*3*5大,所以不满足条件,也就是说如果不连续必然能将其中一个替换的,得到一个更小的数。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int num[31]={0,2,3,5,7,11,13,17,19,23,29,31,33};
long long  i,j,n,ans,best;
void dfs (long long x,long long y,int z)
{
	if (x>best)
	{
	  best=x; ans=y;
	}
	if (x==best&&ans>y)
	{
	   ans=y;
	}
	if (z>11)  return; 
	for (int i=1;i<=50;i++)
	{
	  if (y*num[z]>n)   break;
	  dfs(x*(i+1),y*num[z],z+1);
	  y*=num[z];
	}
}
int main()
{
	scanf("%lld",&n);
	ans=10000000;
	dfs(1,1,1);
	printf("%lld",ans);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值