BZOJ 1053: [HAOI2007]反素数ant
还以为是什么神坑数论题。
看到题,第一眼想到φ,然后暴力。
然后发现暴力其实是有可能的啦。
一个数的因数个数=所有质因数的次数+1,然后乘起来。
例如 60=2^2*3^1*5^1,so g(60)=(2+1)*(1+1)*(1+1)......(后面都是1)=12。
然后我们就要构造(而不是枚举)n范围之内的最大反素了。
1.先打个素数表,13个足够了(我搞了14个)
2.越小的素数次数应该越多越好(贪心)
3.不要开数组统计次数然后每次乘起来(important),纪录一个上次的位置即可。
爆搜不解释
CODE
#include<cstdio> using namespace std; typedef long long LL; const LL pri[15]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43}; //1不会用到 LL c[15],n,ans,num=1; void dfs(LL sum,LL last,LL res) { if (sum>n) return; if (res>ans) ans=res,num=sum; if (res==ans&&sum<num) num=sum; for (int i=last;i<=14;++i) { c[i]++; dfs(pri[i]*sum,i,res/(c[i]-1)*c[i]); c[i]--; } } int main() { scanf("%lld",&n); for (int i=1;i<=14;++i) c[i]=1; dfs(1,1,1); printf("%lld",num); return 0; }
其实不用开c数组(SB)
辣鸡老年选手AFO在即