5 条题解
-
1gscsd LV 7 @ 2017-04-30 14:13:22
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define min(a,b) ((a<b)?a:b)
#define max(a,b) ((a>b)?a:b)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
using namespace std;
int const MxCnt=1e4;
LL Ans,Cnt,Pri[MxCnt+10];
bool CPri(LL N){
int Mx=sqrt(N);
fo(i,2,Mx)if(N%i==0)return 0;
return 1;
}
void Prep(LL N){
Cnt=0;int Mx=sqrt(N);
fo(i,1,Mx)if(N%i==0){
if(CPri(i+1))Pri[++Cnt]=i+1;
if(CPri(N/i+1))Pri[++Cnt]=N/i+1;
}
}
bool Cmp(LL X,LL Y){return X>Y;}
void Dfs(int Pos,LL Y,LL X){
if(Y==1)Ans=min(Ans,X);
if((Pos>Cnt)||(Y==1)||(X>Ans))return;
for(LL i=Pri[Pos]-1;Y%i==0;i*=Pri[Pos])Dfs(Pos+1,Y/i,X/(Pri[Pos]-1)*Pri[Pos]);
Dfs(Pos+1,Y,X);
}
int main(){
//freopen("d.in","r",stdin);
//freopen("d.out","w",stdout);
int T;scanf("%d",&T);
fo(cas,1,T){
LL Y;scanf("%lld",&Y);
Prep(Y);
sort(Pri+1,Pri+Cnt+1,Cmp);
Ans=(Y==1)?Y:Y*10;Dfs(1,Y,Y);
printf("%lld\n",Ans);
}
return 0;
} -
02019-05-26 20:02:06@
/*数论 可以先写个欧拉筛输出前50个phi(x)观察特点 比如计算phi(x)=8的最小的i,结果是15 考虑将x分解为p1^a1*p2^a2*...*pk^ak (唯一分解定理) 则phi(x)=p1^(a1-1)(p1-1)*p2^(a2-1)(p2-1)*...*pn^(ak-1)(pk-1)=n n也可以分解为p1^b1*p2^b2*...*pk^bk,那么x与n同阶且大小接近 用线性筛筛出sqrt(n)内的所有质数,然后暴力搜索答案,尝试用质因子凑出n */ #include<cstdio> #include<cstring> #include<iostream> #define MAXN 50005 typedef long long ll; int n, prime[MAXN]; bool isp[MAXN]; ll ans; void getprime(int a) { memset(isp, 1, sizeof(isp)); for(int i = 2; i <= a; i++) { if(isp[i]) prime[++prime[0]] = i; for(int j = 1; j <= prime[0] && i * prime[j] <= a; j++) { isp[i * prime[j]] = 0; if(i % prime[j] == 0) break; } } } bool IsPrime(ll x) { if(x & 1 ^ 1) return false; for(int i = 2; i * i <= x; i++) if(x % i == 0) return false; return true; } void dfs(int num, int rem, ll res)//num表示当前考虑到第几个质数,rem记录n分解后的剩余,res记录结果 { if(rem == 1) //递归出口 { ans = std::min(ans, res); return ; } if(rem > MAXN - 2 && IsPrime(rem + 1)) //处理较大的质因子,当x+1为质数时,最小的phi(x)就是x+1 { ans = std::min(ans, res * (rem + 1)); //return ; } for(int i = num; i <= prime[0]; i++) if(rem % (prime[i] - 1) == 0) //ans中可以有prime[i]这个质因子 { int newrem = rem / (prime[i] - 1); ll newres = res * prime[i]; dfs(i + 1, newrem, newres); //质因子prime[i]出现一次 while(newrem % prime[i] == 0) //质因子prime[i]出现多次 { newrem /= prime[i]; newres *= prime[i]; dfs(i + 1, newrem, newres); } } } int main() { int t; scanf("%d", &t); getprime(MAXN-1); for(int i=1;i<=t;i++) { scanf("%d",&n); ans = 1LL<<32; dfs(1, n, 1); if(ans == 1LL<<32) printf("-1\n"); else printf("%lld\n", ans); } return 0; }
-
02017-04-25 22:43:05@
打表的好题
-
02016-02-18 10:59:37@
这个我也来
-
-22016-01-10 18:26:11@
虽然我没有AC但我来抢个沙发
- 1
信息
- ID
- 1862
- 难度
- 7
- 分类
- (无)
- 标签
- 递交数
- 164
- 已通过
- 26
- 通过率
- 16%
- 被复制
- 2
- 上传者