T_T终于让我过了,坑啊,竟然时限是200ms。。。
我是预处理出不整除了个数的,因为这个较容易一点。利用算术基本定理,f=p1^a1*p2^a2......
所以,整除它的个数就是(a1+1)*(a2+1)......
开始预处理时,利用线性筛来先求素数,再计算,。。。呃,果断TLE了。后来发度娘告诉我一种令人发指的方法,那就是直接两个循环来求,比较令当前因数为i,循环求能被i整除的。。靠O(n^2)的啊,竟然比我的还要快。
另个求整除的,就直接DFS了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL __int64
using namespace std;
const LL INF=(1ll<<62)+1;
//bool isprime[50005];
//int mprime[50005],cp=0;
int prime[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,53,59};
//int cnt[50005],fac[100];
int findx[50005];
/*
void Init(){
memset(isprime,false,sizeof(isprime));
for(int i=2;i<=50000;i++){
if(!isprime[i]) mprime[cp++]=i;
for(int j=0;j<cp;j++){
if(mprime[j]>50000/i) break;
isprime[i*mprime[j]]=true;
if(i%mprime[j]==0) break;
}
}
}
/*
void WorkBefore(){
int facnt=0;
memset(cnt,0,sizeof(cnt));
memset(findx,0,sizeof(findx));
for(int i=2;i<=50000;i++){
facnt=0;
int ti=i;
for(int k=0;ti/mprime[k]>=mprime[k];k++){
if(ti%mprime[k]==0){
fac[facnt]=0;
while(ti%mprime[k]==0){
ti/=mprime[k];
fac[facnt]++;
}
facnt++;
}
}
if(ti!=1)
fac[facnt]=1,facnt++;
int e=1;
for(int k=0;k<facnt;k++){
e*=(fac[k]+1);
}
cnt[i]=i-e;
if(findx[cnt[i]]==0) findx[cnt[i]]=i;
}
}
*/
void dfs(int pos,int k,LL tans,LL &ans){
if(k==1&&tans<ans) ans=tans;
if(k<=1||tans>=ans) return;
LL t=1;
for(int i=1;i<=62;i++){
t*=prime[pos];
if(k<i+1) break;
if(k%(i+1)==0&&ans/t>=tans){
dfs(pos+1,k/(i+1),tans*t,ans);
}
}
}
void Init(){
for(int i=1;i<=50000;i++) findx[i]=i;
for(int i=1;i<=50000;i++){
for(int j=i;j<=50000;j+=i) findx[j]--;
if(!findx[findx[i]]) findx[findx[i]]=i;
findx[i]=0;
}
}
int main(){
Init();
// WorkBefore();
// cout<<"YES"<<endl;
int T,t=0,type,k;
scanf("%d",&T);
while(T--){
scanf("%d%d",&type,&k);
printf("Case %d: ",++t);
if(type==1){
int ans=-1;
if(findx[k]==0)
printf("Illegal\n");
else printf("%d\n",findx[k]);
}
else{
LL ans=INF;
dfs(0,k,1ll,ans);
if(ans==INF)
printf("INF\n");
else
printf("%I64d\n",ans);
}
}
return 0;
}