Description
__int64 ago,there’s a heaven cow called sjy…
A god bull named wzc fell in love with her…
As an OI & MOer,wzc gave sjy a quesiton…
给定一个整数n,求一个整数m,满足m<=n,并且m/phi(m)的值最大。
注:phi(m)代表m的欧拉函数,即不大于m且与m互质的数的个数。
Input
第一行是一个整数T,表示该测试点有T组数据。
接下来T行,每行一个整数n,意义如上所述。
Output
输出一共T行,每行一个整数m。
若对于某个n,有不止一个满足条件的m,则输出最小的m。
Sample Input
1
10
Sample Output
6
Data Constraint
对于10%的数据, n<=1000
对于30%的数据, n<=10^10
对于60%的数据, n<=10^2000
对于100%的数据,T<=100,n<=10^25000。
思路
首先,我们知道phi(n)=n*(1-1/p1)(1-1/p2)…(1-1/pk)
那么,n/phi(n)=(p1/p1-1)(p2/p2-1)…(pn/pn-1)
明显,就是求质数相乘,满足ans< n
需要高精度压位
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
const long long mod=100000000000;
using namespace std;
long long b[6500][2500],z[6500],t,n,m,a[2500];
char s[100000];
int times(long long x,long long y,long value)
{
long i,j,k,l;
for(i=1; i<=b[x][0]; i++)
{
b[y][i]+=b[x][i]*value;
b[y][i+1]+=b[y][i]/mod;
b[y][i]%=mod;
}
b[y][0]=b[x][0];
if(b[y][b[y][0]+1]>0) b[y][0]++;
}
int check(long long a[2500],long long b[2500])
{
if(b[0]>a[0]) return 1;else if(b[0]<a[0]) return 0; else
{
for(long long i=b[0]; i>=1; i--)
{
if(b[i]>a[i]) return 1;else if(b[i]<a[i]) return 0;
}
}
return 0;
}
int main()
{
scanf("%lld",&t);
long long i,j,k,l,x,y;
for(i=2; i<=60000; i++)
{
bool q=1;
for(j=2; j<=sqrt(i); j++)
{
if(!(i%j)) q=0;
}
if(q)
{
z[++z[0]]=i;
}
}
b[0][0]=1;
b[0][1]=1;
for(i=1; i<=z[0]; i++)
{
times(i-1,i,z[i]);
}
while(t--)
{
scanf("%s",s);
a[0]=0;
k=0;
int len=strlen(s);
l=1;
for(i=1; i<=len; i++)
{
k=k+(s[len-i]-48)*l;
l*=10;
if(l==mod)
{
a[++a[0]]=k;
l=1;
k=0;
}
}
if(k) a[++a[0]]=k;
for(i=1; i<=z[0]; i++)
{
if(check(a,b[i]))
{
for(j=b[i-1][0];j>=1;j--)
{
if(j!=b[i-1][0]) printf("%011lld",b[i-1][j]);else printf("%lld",b[i-1][j]);
}
break;
}
}
printf("\n");
}
}