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)

posted @ 2017-12-15 19:48  空気力学の詩  阅读(121)  评论(0编辑  收藏  举报