【BZOJ 1053】 1053: [HAOI2007]反素数ant (反素数)
1053: [HAOI2007]反素数ant
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
1000Sample Output
840HINT
Source
【分析】
GDXB教我的反素数【一开始看错题了,表示不会求n以内的反素数个数。。。
反素数,仔细想想就有两个重要性质,对dfs有巨大帮助:
(1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小
(2)同样的道理,如果,那么必有
【想一下交换两个指数造成的影响就好了
然后一开始搞错了一个地方,看了黄学长的判断:
if(x>id&&as>ans) ans=as,id=x;
else if(x<=id&&as>=ans) ans=as,id=x;
你可能会觉得第一句的话替换出来的不一定是反素数,但我们可以肯定即使如此我们后面也会用真正的反素数替换它的,所以正确性应该可以确定吧。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define LL long long 8 9 LL pri[15]={10,2,3,5,7,11,13,17,19,23,29,31,37,41}; 10 11 LL ans=0,id=0,n; 12 13 void dfs(LL x,LL nw,LL bf,LL cnt,LL as) 14 { 15 if(x>n||nw>13) return; 16 if(x>id&&as>ans) ans=as,id=x; 17 else if(x<=id&&as>=ans) ans=as,id=x; 18 19 if(cnt<bf) dfs(x*pri[nw],nw,bf,cnt+1,as/(cnt+1)*(cnt+2)); 20 dfs(x,nw+1,cnt,0,as); 21 } 22 23 int main() 24 { 25 scanf("%lld",&n); 26 dfs(1,1,30,0,1); 27 printf("%lld\n",id); 28 return 0; 29 }
好像不用LL 有点迷