题意:给出一个数K,和两个操作,如果操作是0,就求出一个最小的正整数X,满足X的约数个数为K,如果操作是1,就求出一个最小的X,满足X的约数个数为X-K。
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- using namespace std;
- typedef long long LL;
- const int ns=49000,top=15;
- const LL INF=((LL)1<<62)+1;
- LL ans;
- int m,k,type,cnt;
- int ip[ns+10];
- int p[100]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
- void prim()
- {
- int i,j;
- for(i=1;i<=ns;i++) ip[i]=i; //初始化i最多有i个与其互质的数
- for(i=1;i<=ns;i++)
- {
- for(j=i;j<=ns;j+=i) ip[j]--; //i为j的因子,所以j与i不互质,第j个数的互质数减少1
- if(!ip[ip[i]]) ip[ip[i]]=i; //此时ip[i]存的是不大于i的数与i互质的个数k=ip[i],
- //如果ip[k]=0,表示小于i的所有数中,没有刚好有k个互质数的数
- //故将ip[k]=i,表示刚好有k个与i互质的数个数最小为i
- ip[i]=0; //标记刚好有k个互质数的数没有(不大于i的数不可能存在某个数与其互质的数的个数等于i);
- }
- }
- void dfs(int fm,LL t,int pos)
- {
- if (fm==k&&ans>t) ans=t;
- if (fm>=k||(pos>=top)) return ;
- for (int i=1; i<=62; i++)
- {
- if (t>ans/p[pos]||fm*(i+1)>k) break;
- t*=p[pos];
- if (k%(fm*(i+1))==0)
- dfs(fm*(i+1),t,pos+1);
- }
- }
- int main()
- {
- prim();
- int T,cas=0;
- scanf("%d",&T);
- while (T--)
- {
- scanf("%d%d",&type,&k);
- if (type)
- {
- ans=ip[k];
- }
- else
- {
- ans=INF;
- dfs(1,1,0);
- }
- printf("Case %d: ",++cas);
- if (ans==0) printf("Illegal\n");
- else if (ans>=INF) printf("INF\n");
- else printf("%I64d\n",ans);
- }
- return 0;
- }
-
-
- import java.io.BufferedInputStream;
- import java.math.BigInteger;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Map;
- import java.util.Queue;
- import java.util.Scanner;
- class Node
- {
- private static final int MAXP = 60;
- public BigInteger K;
- public long F;
- public int N;
- public int[] A;
- public Node()
- {
- K = BigInteger.ZERO;
- A = new int[MAXP];
- }
- }
- public class Main
- {
- private static final int MAXIP = 250;
- private static final int MAXP = 60;
- private static BigInteger[] prime;
- private static void init()
- {
- boolean[] isPrime = new boolean[MAXIP];
- for(int i=0;i<MAXIP;++i)
- {
- isPrime[i] = true;
- }
- isPrime[0] = isPrime[1] = false;
- for(int i=4;i<MAXIP;i+=2)
- {
- isPrime[i] = false;
- }
- for(int i=3;i<MAXIP;i+=2)
- {
- for(int j=3;i*j<MAXIP;j+=2)
- {
- isPrime[i*j] = false;
- }
- }
- prime = new BigInteger[MAXP];
- for(int i=0, j=0;i<MAXIP;++i)
- {
- if(isPrime[i])
- {
- prime[j++] = BigInteger.valueOf(i);
- }
- }
- }
- public static void main(String args[])
- {
- init();
- List<BigInteger> P = new ArrayList<BigInteger>();
- BigInteger MP = BigInteger.ZERO;
- List<Node> ans = new ArrayList<Node>();
- Scanner cin = new Scanner(new BufferedInputStream(System.in));
- while(cin.hasNext())
- {
- BigInteger temp = cin.nextBigInteger();
- P.add(temp);
- if(temp.compareTo(MP) == 1)
- {
- MP = temp;
- }
- ans.add(new Node());
- }
- Map<Long, BigInteger> map = new HashMap<Long, BigInteger>();
- Queue<Node> queue = new LinkedList<Node>();
- Node origin = new Node();
- origin.K = BigInteger.ONE;
- origin.F = 1;
- origin.N = 0;
- queue.add(origin);
- map.put(origin.F, origin.K);
- while(!queue.isEmpty())
- {
- Node u = queue.peek();
- queue.remove();
- BigInteger compare = map.get(u.F);
- if(compare != null)
- {
- if(compare.compareTo(u.K) == -1)
- {
- continue;
- }
- }
- for(int i=0;i<P.size();++i)
- {
- if(u.K.compareTo(P.get(i)) <= 0)
- {
- if(u.F > ans.get(i).F)
- {
- ans.get(i).F = u.F;
- ans.get(i).K = u.K;
- }
- else if(u.F == ans.get(i).F)
- {
- if(u.K.compareTo(ans.get(i).K) == -1)
- {
- ans.get(i).K = u.K;
- }
- }
- }
- }
- for(int i=0;i<u.N;++i)
- {
- Node v = new Node();
- v.K = u.K.multiply(prime[i]);
- if(v.K.compareTo(MP) <= 0)
- {
- v.F = u.F / (u.A[i] + 1) * (u.A[i] + 2);
- v.N = u.N;
- for(int j=0;j<u.N;++j)
- {
- v.A[j] = u.A[j];
- }
- ++ v.A[i];
- boolean flag = true;
- compare = map.get(v.F);
- if(compare != null)
- {
- if(compare.compareTo(v.K) <= 0)
- {
- flag = false;
- }
- else
- {
- map.remove(v.F);
- }
- }
- if(flag)
- {
- queue.add(v);
- map.put(v.F, v.K);
- }
- }
- }
- Node v = new Node();
- v.K = u.K.multiply(prime[u.N]);
- if(v.K.compareTo(MP) <= 0)
- {
- v.F = u.F * 2;
- v.N = u.N + 1;
- for(int i=0;i<u.N;++i)
- {
- v.A[i] = u.A[i];
- }
- ++ v.A[u.N];
- boolean flag = true;
- compare = map.get(v.F);
- if(compare != null)
- {
- if(compare.compareTo(v.K) <= 0)
- {
- flag = false;
- }
- else
- {
- map.remove(v.F);
- }
- }
- if(flag)
- {
- queue.add(v);
- map.put(v.F, v.K);
- }
- }
- }
- for(int i=0;i<ans.size();++i)
- {
- System.out.println(ans.get(i).K.toString() + " " + ans.get(i).F); //第一个数为满足因子个数最多的K,第二个数为K的因子个数
- }
- }
- }