https://www.lydsy.com/JudgeOnline/problem.php?id=3737
https://szkopul.edu.pl/problemset/problem/5LCCf9uDmKEBYhuzP7iT-8SM/site/?key=statement
根据欧拉函数那个式子,设a分解质因数后为a1^p1*a2^p2*..*ak^pk,a的欧拉函数就等于(a1-1)*a1^(p1-1)*(a2-1)*a2^(p2-1)*..*(ak-1)*ak^(pk-1)
那么,暴力枚举给出n的所有因子,将它们全部+1,然后只保留它们中的质数,那么x的质因子只可能在这些质数中产生
这样的质数不多,爆搜就好了。。。当然如果n是1要特判一下,直接输出1和2
好吧,直接爆搜会T飞。。。
我在网上找到了解决方法:
设当前还要构造出的欧拉函数值为nowphi,如果还要拆成两个或以上个数的积,那么其中最小数一定<=sqrt(nowphi);如果当前要考虑的最小的质数-1(是最小的可能的因子)也>sqrt(nowphi),那么自然不可能拆成两个或以上的个数的积
现在唯一可能是nowphi单独作为一项存在;要求是,nowphi+1>=当前考虑质数(不然在其他情况会考虑到),且nowphi+1是质数
这是一个大剪枝,可以A了。。。貌似复杂度还是有保证的?https://www.bbsmax.com/A/B0zq67P8Jv/
讲不清楚。。。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<map> 6 #include<cmath> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 typedef pair<ll,ll> pii; 15 16 namespace M 17 { 18 //不会...板子先贴过来 19 const ll prime[] = {2, 3, 7, 61, 24251}; 20 const ll MT = 5; 21 inline ll mulmod(ll x, ll y, ll mod) 22 { 23 ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod); 24 return tmp<0?tmp+mod:tmp; 25 } 26 inline ll powermod(ll a, ll b, ll k) 27 { 28 ll re = 1, temp = a; 29 while (b) 30 { 31 if (b & 1) 32 re = mulmod(re, temp, k); 33 temp = mulmod(temp, temp, k); 34 b >>= 1; 35 } 36 return re; 37 } 38 ll TwiceDetect(ll a, ll b, ll k) 39 { 40 ll t = 0; 41 ll x, y; 42 while ((b & 1) == 0) 43 { 44 b >>= 1; 45 t++; 46 } 47 y = x = powermod(a, b, k); 48 while (t--) 49 { 50 y = mulmod(x, x, k); 51 if (y == 1 && x != 1 && x != k - 1) 52 return 0; 53 x = y; 54 } 55 return y; 56 } 57 bool Miller_Rabin(ll n) 58 { 59 ll i; 60 ll tmp; 61 for (i = 0; i < MT; i++) 62 { 63 tmp = prime[i]; 64 if (n == prime[i]) 65 return true; 66 if (TwiceDetect(tmp, n - 1, n) != 1) 67 break; 68 } 69 return (i == MT); 70 } 71 } 72 using M::Miller_Rabin; 73 74 const ll N=1000000; 75 bool nprime[1001000]; 76 ll prime[201000],len; 77 bool isprime(ll x) 78 { 79 if(x>N) return Miller_Rabin(x); 80 else return !nprime[x]; 81 } 82 83 ll T; 84 ll n; 85 ll tt[1001],tp; 86 ll an[1010100],tpa; 87 void dfs(ll p,ll now,ll nowphi) 88 { 89 if(nowphi==1) 90 { 91 an[++tpa]=now; 92 return; 93 } 94 if(p>tp) return; 95 if(tt[p]-1>sqrt(nowphi)) 96 { 97 if(nowphi+1>=tt[p]&&isprime(nowphi+1)) 98 an[++tpa]=now*(nowphi+1); 99 return; 100 } 101 dfs(p+1,now,nowphi); 102 if((long double)now*tt[p]>=1e18) return; 103 now*=tt[p]; 104 if(nowphi%(tt[p]-1)!=0) return; 105 nowphi/=(tt[p]-1); 106 dfs(p+1,now,nowphi); 107 while(1) 108 { 109 if((long double)now*tt[p]>=1e18) return; 110 now*=tt[p]; 111 if(nowphi%tt[p]!=0) return; 112 nowphi/=tt[p]; 113 dfs(p+1,now,nowphi); 114 } 115 } 116 int main() 117 { 118 //freopen("/tmp/3737/7.in","r",stdin); 119 //freopen("/tmp/3737/7.ans","w",stdout); 120 ll i,j,ed; 121 nprime[1]=1; 122 for(i=2;i<=N;i++) 123 { 124 if(!nprime[i]) prime[++len]=i; 125 for(j=1;j<=len&&i*prime[j]<=N;j++) 126 { 127 nprime[i*prime[j]]=1; 128 if(i%prime[j]==0) break; 129 } 130 } 131 scanf("%lld",&T); 132 while(T--) 133 { 134 scanf("%lld",&n); 135 if(n==1) 136 { 137 puts("2"); 138 puts("1 2"); 139 continue; 140 } 141 tp=0; 142 ed=sqrt(n+0.5); 143 for(i=1;i<=ed;i++) 144 if(n%i==0) 145 { 146 if(isprime(i+1)) tt[++tp]=i+1; 147 if(ll(i)*i!=n&&isprime(n/i+1)) tt[++tp]=n/i+1; 148 } 149 sort(tt+1,tt+tp+1); 150 tpa=0;dfs(1,1,n); 151 sort(an+1,an+tpa+1); 152 printf("%lld ",tpa); 153 for(i=1;i<=tpa;i++) printf("%lld%c",an[i]," "[i==tpa]); 154 if(!tpa) puts(""); 155 } 156 return 0; 157 }
耶,卡到第一了!
卡常版代码:
1 #pragma GCC optimize(3) 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #include<map> 7 #include<cmath> 8 using namespace std; 9 #define fi first 10 #define se second 11 #define mp make_pair 12 #define pb push_back 13 typedef long long ll; 14 typedef unsigned long long ull; 15 16 namespace M 17 { 18 //不会...板子先贴过来 19 const ll prime[] = {2, 3, 7, 61, 24251}; 20 const ll MT = 5; 21 inline ll mulmod(ll x, ll y, ll mod) 22 { 23 ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod); 24 return tmp<0?tmp+mod:tmp; 25 } 26 inline ll powermod(ll a, ll b, ll k) 27 { 28 ll re = 1, temp = a; 29 while (b) 30 { 31 if (b & 1) 32 re = mulmod(re, temp, k); 33 temp = mulmod(temp, temp, k); 34 b >>= 1; 35 } 36 return re; 37 } 38 ll TwiceDetect(ll a, ll b, ll k) 39 { 40 ll t = 0; 41 ll x, y; 42 while ((b & 1) == 0) 43 { 44 b >>= 1; 45 t++; 46 } 47 y = x = powermod(a, b, k); 48 while (t--) 49 { 50 y = mulmod(x, x, k); 51 if (y == 1 && x != 1 && x != k - 1) 52 return 0; 53 x = y; 54 } 55 return y; 56 } 57 bool Miller_Rabin(ll n) 58 { 59 ll i; 60 ll tmp; 61 for (i = 0; i < MT; i++) 62 { 63 tmp = prime[i]; 64 if (n == prime[i]) 65 return true; 66 if (TwiceDetect(tmp, n - 1, n) != 1) 67 break; 68 } 69 return (i == MT); 70 } 71 } 72 using M::Miller_Rabin; 73 74 const ll N=500000; 75 bool nprime[501000]; 76 ll prime[200100],len; 77 bool isprime(ll x) 78 { 79 return x>N?Miller_Rabin(x):!nprime[x]; 80 } 81 82 ll tt[1001],*tp=tt; 83 ll an[1010100],*tpa=an; 84 ll now,nowphi; 85 void dfs(ll *p,ll now,ll nowphi) 86 { 87 if(nowphi==1) 88 { 89 *(++tpa)=now; 90 return; 91 } 92 if(p>tp) return; 93 if(*p-1>sqrt(nowphi)) 94 { 95 if(nowphi+1>=*p&&isprime(nowphi+1)) 96 *(++tpa)=now*(nowphi+1); 97 return; 98 } 99 dfs(p+1,now,nowphi); 100 //if((long double)now*(*p)>=1e18) return; 101 now*=(*p); 102 if(nowphi%((*p)-1)!=0) return; 103 nowphi/=((*p)-1); 104 dfs(p+1,now,nowphi); 105 while(1) 106 { 107 //if((long double)now*(*p)>=1e18) return; 108 now*=(*p); 109 if(nowphi%(*p)!=0) return; 110 nowphi/=(*p); 111 dfs(p+1,now,nowphi); 112 } 113 } 114 int T; 115 ll n; 116 int main() 117 { 118 //freopen("/tmp/3737/18.in","r",stdin); 119 //freopen("/tmp/3737/18.ans","w",stdout); 120 int i,j,ed; 121 nprime[1]=1; 122 for(i=2;i<=N;i++) 123 { 124 if(!nprime[i]) prime[++len]=i; 125 for(j=1;j<=len&&i*prime[j]<=N;j++) 126 { 127 nprime[i*prime[j]]=1; 128 if(i%prime[j]==0) break; 129 } 130 } 131 scanf("%d",&T); 132 while(T--) 133 { 134 scanf("%lld",&n); 135 if(n==1) 136 { 137 puts("2"); 138 puts("1 2"); 139 continue; 140 } 141 tp=tt; 142 ed=sqrt(n+0.5); 143 for(i=1;i<=ed;i++) 144 if(n%i==0) 145 { 146 if(isprime(i+1)) *(++tp)=i+1; 147 if(ll(i)*i!=n&&isprime(n/i+1)) *(++tp)=n/i+1; 148 } 149 sort(tt+1,tp+1); 150 tpa=an;dfs(tt+1,1,n); 151 sort(an+1,tpa+1); 152 int ttttt=tpa-an; 153 printf("%d ",ttttt); 154 for(i=1;i<=ttttt;i++) printf("%lld%c",an[i]," "[i==ttttt]); 155 if(!ttttt) puts(""); 156 } 157 return 0; 158 }
https://www.luogu.org/problemnew/show/P4780
减弱版?
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<map> 6 #include<cmath> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 typedef pair<ll,ll> pii; 15 16 namespace M 17 { 18 //不会...板子先贴过来 19 const ll prime[] = {2, 3, 7, 61, 24251}; 20 const ll MT = 5; 21 inline ll mulmod(ll x, ll y, ll mod) 22 { 23 ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod); 24 return tmp<0?tmp+mod:tmp; 25 } 26 inline ll powermod(ll a, ll b, ll k) 27 { 28 ll re = 1, temp = a; 29 while (b) 30 { 31 if (b & 1) 32 re = mulmod(re, temp, k); 33 temp = mulmod(temp, temp, k); 34 b >>= 1; 35 } 36 return re; 37 } 38 ll TwiceDetect(ll a, ll b, ll k) 39 { 40 ll t = 0; 41 ll x, y; 42 while ((b & 1) == 0) 43 { 44 b >>= 1; 45 t++; 46 } 47 y = x = powermod(a, b, k); 48 while (t--) 49 { 50 y = mulmod(x, x, k); 51 if (y == 1 && x != 1 && x != k - 1) 52 return 0; 53 x = y; 54 } 55 return y; 56 } 57 bool Miller_Rabin(ll n) 58 { 59 ll i; 60 ll tmp; 61 for (i = 0; i < MT; i++) 62 { 63 tmp = prime[i]; 64 if (n == prime[i]) 65 return true; 66 if (TwiceDetect(tmp, n - 1, n) != 1) 67 break; 68 } 69 return (i == MT); 70 } 71 } 72 using M::Miller_Rabin; 73 74 const ll N=1000000; 75 bool nprime[1001000]; 76 ll prime[201000],len; 77 bool isprime(ll x) 78 { 79 if(x>N) return Miller_Rabin(x); 80 else return !nprime[x]; 81 } 82 83 ll T; 84 ll n; 85 ll tt[1001],tp; 86 ll an=0x3f3f3f3f3f3f3f3f; 87 void dfs(ll p,ll now,ll nowphi) 88 { 89 if(nowphi==1) 90 { 91 an=min(an,now); 92 return; 93 } 94 if(p>tp) return; 95 if(tt[p]-1>sqrt(nowphi)) 96 { 97 if(nowphi+1>=tt[p]&&isprime(nowphi+1)) 98 an=min(an,now*(nowphi+1)); 99 return; 100 } 101 dfs(p+1,now,nowphi); 102 if((long double)now*tt[p]>2147483648) return; 103 now*=tt[p]; 104 if(nowphi%(tt[p]-1)!=0) return; 105 nowphi/=(tt[p]-1); 106 dfs(p+1,now,nowphi); 107 while(1) 108 { 109 if((long double)now*tt[p]>2147483648) return; 110 now*=tt[p]; 111 if(nowphi%tt[p]!=0) return; 112 nowphi/=tt[p]; 113 dfs(p+1,now,nowphi); 114 } 115 } 116 int main() 117 { 118 //freopen("/tmp/3737/7.in","r",stdin); 119 //freopen("/tmp/3737/7.ans","w",stdout); 120 ll i,j,ed; 121 nprime[1]=1; 122 for(i=2;i<=N;i++) 123 { 124 if(!nprime[i]) prime[++len]=i; 125 for(j=1;j<=len&&i*prime[j]<=N;j++) 126 { 127 nprime[i*prime[j]]=1; 128 if(i%prime[j]==0) break; 129 } 130 } 131 scanf("%lld",&n); 132 if(n==1) 133 { 134 puts("1"); 135 return 0; 136 } 137 tp=0; 138 ed=sqrt(n+0.5); 139 for(i=1;i<=ed;i++) 140 if(n%i==0) 141 { 142 if(isprime(i+1)) tt[++tp]=i+1; 143 if(ll(i)*i!=n&&isprime(n/i+1)) tt[++tp]=n/i+1; 144 } 145 sort(tt+1,tt+tp+1); 146 dfs(1,1,n); 147 if(an<2147483648) printf("%lld",an); 148 else printf("%d",-1); 149 return 0; 150 }