首页 > 其他 > 详细

3629: [JLOI2014]聪明的燕姿|约数和|DFS

时间:2016-03-19 10:05:43      阅读:246      评论:0      收藏:0      [点我收藏+]

M(x)x的约数和,那么考虑约数和的求法,约数和显然是一个积性函数。

x=pt11?pt22?pt33?......?ptnn

那么
M(x)=c1=0t1pc11?c2=0t2pc22?c3=0t3pc33?......?cn=0tnpcnn

这样就可以考虑枚举质因子DFS转化为子问题继续求解。
dfs(now,pos,rest)是指搜索枚举到第pos个质因子,当前值为now,然后剩余的因子的和为rest时的解
搜索时枚举n?的质因子,并且单独判断rest?1是否为质数,这样可以保证搜出来的解没有重复。

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<complex>
#include<queue>
#include<map>
#include<set>
#define N 45000
#define ll long long
using namespace std;
int top,a[N],prime[N],ans[N];
int n,tot;
void get_prime()
{
    for(int i=2;i<N;i++)
    {
        if(!a[i])
            prime[++top]=i;
        for(int j=1;prime[j]*i<N;j++)
        {
            a[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }
}
bool jud(int x)
{
    if(x==1)return 0;
    for(int i=1;prime[i]*prime[i]<=x;i++)
        if(x%prime[i]==0)return 0;
    return 1;
}
void dfs(int now,int pos,int rest)
{
    if(rest==1)
    {
        ans[++tot]=now;
        return;
    }
    if(rest-1>=prime[pos]&&jud(rest-1))
        ans[++tot]=(rest-1)*now;
    for(int i=pos;prime[i]*prime[i]<=rest;i++)
        for(ll p=prime[i],sum=p+1;sum<=rest;p*=prime[i],sum+=p)
            if(rest%sum==0)
                dfs(now*p,i+1,rest/sum);
}
int main()
{
    get_prime();
    while(scanf("%d",&n)!=EOF)
    {
        tot=0;
        dfs(1,1,n);
        sort(ans+1,ans+tot+1);
        printf("%d\n",tot);
        for(int i=1;i<=tot;i++)
            printf("%d%c",ans[i],i==tot?‘\n‘:‘ ‘);
    }
    return 0;
}

3629: [JLOI2014]聪明的燕姿|约数和|DFS

原文:http://blog.csdn.net/ws_yzy/article/details/50929647

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!