0
我在SPOJ上做了這個問題。 www.spoj.com/problems/TIP1。 我已經寫了這段代碼,但我在判斷時超出了時間限制。任何人都可以幫助我進行任何優化或更好的方法。如果N是正整數,則PHI(N)是其中GCD(N,K)= 1且1≤K≤N的整數K的數目。我們表示GCD是最大公約數。例如,我們有PHI(9)= 6。歐拉的托特函數排列
#include<iostream>
#include<vector>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000010
#define MAXN 10000010
int phi[MAXN + 1], prime[MAXN/10], sz=0;
vector<bool> mark(MAXN + 1);
int ans[10000011];
vector<int> a(10);
vector<int> b(10);
bool isprm(long int x)
{
for(int s=0; s<10; s++)
{
a[s]=b[s]=0;
}
long int y=phi[x];
int i=0,j=0;
while(x>0)
{
int rem=x%10;
x=x/10;
a[i]=rem;
i++;
}
while(y>0)
{
int rem=y%10;
y=y/10;
b[j]=rem;
j++;
}
sort(a.begin(), a.end());
sort(b.begin(), b.end());
if(i!=j)
return false;
for(int s=0; s<10; s++)
{
if(a[s]!=b[s])
return false;
}
return true;
}
void precompute_again()
{
for(int i=0; i<=20; ++i)
ans[i]=0;
ans[21]=21;
for(long int i=22; i<10000005; ++i){
bool chk=false;
chk=isprm(i);
if(chk==true)
{
if(i*phi[ans[i-1]]==phi[i]*ans[i-1])
{
ans[i]=i;
}
else
{
if(i*phi[ans[i-1]]>phi[i]*ans[i-1])
{
ans[i]=ans[i-1];
}
else
{
ans[i]=i;
}
}
}
else
{
ans[i]=ans[i-1];
}
}
}
int main()
{
phi[1] = 1;
for (int i = 2; i <= MAXN; i++){
if(!mark[i]){
phi[i] = i-1;
prime[sz++]= i;
}
for (int j=0; j<sz && prime[j]*i <= MAXN; j++){
mark[prime[j]*i]=1;
if(i%prime[j]==0){
int ll = 0;int xx = i;
while(xx%prime[j]==0)
{
xx/=prime[j];
ll++;
}
int mm = 1;
for(int k=0;k<ll;k++)mm*=prime[j];
phi[i*prime[j]] = phi[xx]*mm*(prime[j]-1);
break;
}
else phi[i*prime[j]] = phi[i]*(prime[j]-1);
}
}
precompute_again();
int t;
scanf("%d",&t);
while(t--)
{
long int m;
scanf("%ld",&m);
cout<<ans[m]<<endl;
}
return 0;
}