您的位置:首页 > 其它

1053: [HAOI2007]反素数ant

2016-06-03 16:56 288 查看

1053: [HAOI2007]反素数ant

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2581  Solved: 1454

[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]


爆搜爆搜爆搜

如果知道一个数的质因数组成,就能知道它的因数个数

设x分解质因数后,不同的质数分别是a1,a2,a3,...an

它们的个数分别是b1,b2,b3,...bn

那么x的因数个数为∏(bi+1)

显然,答案需要的是[1,n]内因数最多且它本身大小最小的数

这样的数分解质因数后它的质因数都不会很大

我们随便拿前30个质数,每个质数预处理30次方

这样就能搜索了





一开始没注意本身大小最小这一条件



#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

typedef long long LL;
LL INF = 2000000000;

LL a2,mi[51][31],pri[1000];
int a1,n,tot;
bool p[100000];

void dfs(int x,LL p,LL q)
{
if (x == 31) return;
if (p*(1LL<<(31-x)) < a2) return;
if (p > a2) a1 = q,a2 = p;
if (p == a2 && q < a1) a1 = q;
for (int j = 1; j <= 30; j++) {
if (mi[x][j] == 0) break;
if (q*mi[x][j] > n) break;
dfs(x+1,p*1LL*(j+1),q*mi[x][j]);
}
dfs(x+1,p,q);
}

int main()
{
#ifdef YZY
freopen("yzy.txt","r",stdin);
#endif

cin >> n;
for (int i = 2; i < 100000; i++)
if (!p[i]){
int j = i*2;
while (j < 100000)
{p[j] = 1; j += i;}
}
for (int i = 2; i < 1000; i++)
if (!p[i]) pri[++tot] = i;
for (int i = 1; i <= 50; i++) {
mi[i][0] = 1;
for (int j = 1; j <= 30; j++) {
mi[i][j] = mi[i][j-1]*pri[i];
if (mi[i][j] >= INF) break;
}
}
dfs(1,1,1);
cout << a1;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: