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
HINT
对于100%的数据,T<=100,n<=10^25000<-尼玛这两玩意神坑
T组数据,求
min{kΦ(k)∣1≤k≤n}
。
稍微分析一下
Φ(m)=mΠp∣m(1−1p)
用这个除m的话,就是
1Πp∣m(1−1p)
这个东西要最大就是这个东西的下面最小
如果要最小的话那就要尽量多的分数
又因为这些质数都不相同,要尽量多的话只能是从2开始一长串连续的质数
也就是
2∗3∗5∗7
……直到刚好不大于n
这就是答案
然而!要!高精度!乘法!而且!要!压位!
不要脸地上了发模板
还是T了一发。。。淦。。。
想要不T的话还是要一点trick
比如离线排序,每次保留上一次的结果。
好蛋疼啊QAQ
High_Num A , B , t , n[100];
const int maxn = 5000001;
int prime[100001] , tot , vis[maxn] , T , rec = 1;
void GetPrime() {
for(int i = 2 ; i < maxn ; i ++) {
if (!vis[i]) prime[++ tot] = i;
for(int j = 1 ; j <= tot && (long long)i * prime[j] < maxn ; j ++) vis[i * prime[j]] = 1;
}
}
void solve(int id) {
int tmp = n[id].id;
for(;;rec ++) {
B = A * prime[rec];
if (B > n[id]) break;
A = B;
}
n[id] = A , n[id].id = tmp;
}
int main() {
scanf("%d" , &T);
GetPrime();
A.create(1);
for(int i = 0; i < T; i ++) n[i].read() , n[i].id = i;
sort(n , n + T , smaller);
for(int i = 0; i < T; i ++) solve(i);
for(int i = 0; i < T; i ++) for(int j = 0 ; j < T; j ++)
if (n[j].id == i) { n[j].print() ; break; }
return 0;
}