luoguP1463 [HAOI2007]反素数
Posted tpgzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP1463 [HAOI2007]反素数相关的知识,希望对你有一定的参考价值。
题目描述
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么?
输入输出格式
输入格式:
一个数N(1<=N<=2,000,000,000)。
输出格式:
不超过N的最大的反质数。
输入输出样例
输入样例#1: 复制
1000
输出样例#1: 复制840
思路:一看这道题,不用说这是个数论,作为数学渣渣的我只好去看题解了,发现了这么有趣的一个规律。x=∏pi^ki
其中p是质数,k是指数,那么因数的个数就是(k[1]+1)(k[2]+1)…..(k[n]+1)我们知道了这个规律,我们就可以打表搜索了
代码:
1 #include<iostream> 2 #include<cstdio> 3 #define ll long long 4 using namespace std; 5 ll n; 6 ll maxn,ans;//maxn是更新因数的个数的,ans更新当前的答案 7 int p[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51}; 8 void dfs(ll m,ll f,ll t,ll pr) 9 { 10 if(t>maxn||(t==maxn)&&m<ans)//当此时的因数大与最优解的约数的个数,或者当他等于最优解,但是m小时,看题目中反素数的性质,更新最大约数,更新答案 11 { 12 ans=m; 13 maxn=t; 14 } 15 ll i=m,j=0,nt=0;//j代表当前的指数,因为指数应该是单调递减的所以枚举[j,pr)区间就可以了 16 //i是这个数的大小,nt是因数的个数 17 while(j<pr)//循环结束的条件 18 { 19 j++;//指数增加 20 if(n/i<p[f])break;//如果乘了这个数超过了n就结束。 21 nt=t*(j+1),i*=p[f];//这个数需要乘以这个质数,还有因数的个数改变 22 if(i<=n)dfs(i,f+1,nt,j);//如果这个数还没有超过,那么进行下一层dfs 23 } 24 } 25 int main() 26 { 27 cin>>n; 28 dfs(1,1,1,32); 29 cout<<ans; 30 return 0; 31 }
以上是关于luoguP1463 [HAOI2007]反素数的主要内容,如果未能解决你的问题,请参考以下文章