BZOJ 3629 JLOI2014 聰明的燕姿 約數和+DFS
阿新 • • 發佈:2017-07-15
ini pri spa etc ont read size void logs
根據約數和公式來拆s,最後再把答案乘出來,我們發先這樣的話遞歸層數不會太大每層枚舉次數也不會太多,然而我們再來個剪枝就好了
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<vector> using namespace std; inline int read() { int sum=0; char ch=getchar(); while(ch<‘0‘||ch>‘9‘)ch=getchar();while(ch>=‘0‘&&ch<=‘9‘) { sum=(sum<<1)+(sum<<3)+ch-‘0‘; ch=getchar(); } return sum; } vector<int> ans; int is[50000],Max=50000,prime[50000],sz; inline void Init() { for(int i=2;i<Max;i++) { if(!is[i]) prime[++sz]=i; for(intj=1;prime[j]*i<Max;j++) { is[prime[j]*i]=1; if(i%prime[j]==0)break; } } } inline bool jud(int x) { if(x==1)return 0; int lim=(int)sqrt(x+0.5); for(int i=1;prime[i]<=lim;i++) if(x%prime[i]==0) return 0; return 1; } void dfs(int x,int s,intAns) { if(s==1) { ans.push_back(Ans); return; } int lim=(int)sqrt(s+0.5); if(prime[x]>lim) { if(jud(s-1)&&s-1>=prime[x]) { Ans*=s-1; ans.push_back(Ans); } return; } long long sum=0,get=1; for(int i=0;sum<=s;i++) { sum+=get; if(s%sum==0) dfs(x+1,s/sum,Ans*get); get*=prime[x]; } } int main() { //freopen("swallow.in","r",stdin); //freopen("swallow.out","w",stdout); int s; Init(); while(scanf("%d",&s)==1) { ans.clear(); dfs(1,s,1); printf("%d\n",ans.size()); if(ans.size()==0)continue; sort(ans.begin(),ans.end()); for(int i=0;i<ans.size();i++) printf("%d ",ans[i]); printf("\n"); } return 0; }
BZOJ 3629 JLOI2014 聰明的燕姿 約數和+DFS