【NOIP 模拟题】【bzoj 3643】Phi的反函数(数论+搜索)
2016-10-05 18:49
513 查看
【题解】【数论+dfs】
【其实题面已经昭示了该怎么做,因为做法就是上面给的两个式子。】
【那么,由题意:筛素数,然后直接dfs查找,暴力凑(p1-1) * (p2-1) * …… * (pm-1),然后将n与其相除后验证是否是这些数的倍数即可。】
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int prime[100010],cnt,n,m; bool vis[100010]; ll ans; inline void search() { for(int i=2;i<=50000;++i) { if(!vis[i]) prime[++cnt]=i; for(int j=1;j<=cnt;++j) { if(i*prime[j]>50000) break; vis[i*prime[j]]=1; if(!(i%prime[j])) break; } } } inline bool pd(ll x) { ll k=sqrt(x); for(int i=1;i<=cnt;++i) { if(prime[i]>k) break; if(!(x%prime[i])) return 0; } return 1; } void dfs(int last,int now,ll sum) { if(sum>=ans) return; if(now==1) {ans=sum; return;} if(now>m&&pd(now+1)) ans=min(ans,sum*((ll)now+1)); for(int i=last+1;i<=cnt;++i) { if(prime[i]-1>m) break; if(prime[i]-1>now) break; if(!(now%(prime[i]-1))) { int x=now/(prime[i]-1); ll y=sum*prime[i]; dfs(i,x,y); while(!(x%prime[i])) { x/=prime[i]; y*=prime[i]; dfs(i,x,y); } } } } int main() { freopen("phi.in","r",stdin); freopen("phi.out","w",stdout); int i,j; search(); scanf("%d",&n); ans=2147483648; m=sqrt(n); dfs(1,n,1); if(ans>=2147483648) printf("-1\n"); else printf("%I64d\n",ans); return 0; }
相关文章推荐
- 【BZOJ-3643】Phi的反函数 数论 + 搜索
- bzoj 3643:Phi的反函数 (数论+搜索)
- BZOJ3643 Phi的反函数(数论+搜索)
- BZOJ 3643|Phi的反函数|搜索|线性筛法
- [BZOJ3643]Phi的反函数(数论+dfs)
- [BZOJ3643]Phi的反函数(数学相关+搜索)
- 【BZOJ 3643】Phi的反函数 数搜索
- BZOJ 3643: Phi的反函数 搜索
- bzoj3643 Phi的反函数
- BZOJ 3643 Phi的反函数
- 【BZOJ3643】phi的反函数,暴搜
- [BZOJ3643] phi的反函数 - 欧拉函数 - dfs
- BZOJ 3643 Phi的反函数
- NOIP模拟题 2016.11.11 [搜索] [动态规划] [网络流] [字符串处理]
- NOIP模拟题 2016.10.29 [DP] [中位数相关] [折半搜索]
- NOIP模拟题 2016.11.2 [数论]
- NOIP模拟题 2016.11.8 (2) [线段树] [动态逆序对] [矩阵快速幂] [数论] [欧拉函数]
- noip搜索模拟题 骰子
- NOIP模拟题 2016.11.17 [数论] [数位DP] [扫描线] [线段树]
- 【BZOJ 3642】Phi的反函数