首页 > 代码库 > 【BZOJ-3643】Phi的反函数 数论 + 搜索
【BZOJ-3643】Phi的反函数 数论 + 搜索
3643: Phi的反函数
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 141 Solved: 96
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
4
Sample Output
5
HINT
Source
By Zky
Solution
首先答案和N一定是同阶的,所以,可以很暴力的线筛扫一遍求解。
然后根据欧拉函数的式子,我们实际上是可以爆搜的。
爆搜他的质因子然后去凑答案,加最优性剪枝就可以跑过。
最关键的是依据欧拉函数的定义式找到规律!
Code
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>using namespace std;#define LL long longinline 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;}#define MAXN 5100000int X,N;int prime[MAXN],flag[MAXN],cnt;void Getprime(){ flag[1]=1; cnt=0; for (int i=2; i<=N; i++) { if (!flag[i]) prime[++cnt]=i; for (int j=1; j<=cnt && prime[j]*i<=N; j++) { flag[i*prime[j]]=1; if (prime[j]%i==0) break; } }}LL ans=(1LL<<30);LL sqr(LL x) {return (LL)x*x;}bool check(int x) {// if (flag[x]) return 0; for (int i=1; sqr(prime[i])<=x && i<=cnt; i++) if (x%prime[i]==0) return 0; return 1;}void DFS(int dep,LL sum,LL x,int last){ if (sum>=ans) return; if (x==1) {ans=sum; return;} if (check(x+1) && sqr(x)>X) ans=min(ans,sum*(x+1)); for (int i=last+1; (prime[i]-1)<=x && sqr(prime[i]-1)<=X; i++) if (!(x%(prime[i]-1))) { LL xx=(LL)x/(prime[i]-1),summ=(LL)sum*prime[i]; DFS(dep+1,summ,xx,i); while (!(xx%prime[i])) xx=(LL)xx/prime[i],summ=(LL)summ*prime[i],DFS(dep+1,summ,xx,i); }}int main(){ X=read(); N=int(sqrt(X))+1010; if (X==1) {puts("1"); return 0;} Getprime(); DFS(1,1LL,(LL)X,1); printf("%lld\n",ans==(1LL<<30)? -1:ans); return 0;}
仔细思考一下应该是可以想到的。
【BZOJ-3643】Phi的反函数 数论 + 搜索
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。