bzoj3629 [JLOI2014]聪明的燕姿

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3629

题目大意:给定一个N,输出所有正约数之和等于N的数。

题目分析:dfs即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=1000008;
int d;
int n;
int ans=0,way[110000];
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
bool mark[maxn];
int prim[maxn],primm;
void Get_Prime()
{
    for (int i=2;i<=100000;i++)
	{ 
        if (!mark[i]) prim[++primm]=i;
        for (int j=1;prim[j] * i<=100000;j++)
		{
            mark[prim[j]*i]=true;
            if (i%prim[j]==0) break;
        }
    }
}

bool isprime(int x)
{
	if (x<=100000) return (!mark[x]);
	int d=sqrt(x);
	for (int i=2;i<=d;i++)
	  if (x%i==0) return false;
	return true;
}
void dfs(int last,int now,int num)
{
	if (now==1)
	{
		ans++;
		way[ans]=num;
		return;
	}
	if (now-1>d&&isprime(now-1))
	{
		ans++;
		way[ans]=num*(now-1);
	}
	for (int i=last+1;prim[i]<=d;i++)
	{
		LL cal=1,t=prim[i];
		for (int j=1;cal+t<=now;j++)
		{
			cal+=t;
			if (now%cal==0) dfs(i,now/cal,num*t);
			t*=prim[i];
		}
	}
}
int main()
{
	while (scanf("%d",&n)==1)
	{
		ans=0;
		d=sqrt(n);
    	Get_Prime();
    	dfs(0,n,1);
    	sort(way+1,way+1+ans);
   	 	cout<<ans<<endl;
    	for (int i=1;i<=ans;i++)
    	{
    		printf("%d",way[i]);
    		if (i!=ans) printf(" ");
    	       	  else printf("\n");
		}
	} 
	return 0;
}


你可能感兴趣的:(bzoj3629 [JLOI2014]聪明的燕姿)