A. k-th divisor
You are given two integers n and k. Find k-th smallest divisor of n, or report that it doesn’t exist.
Divisor of n is any such natural number, that n can be divided by it without remainder.
Input
The first line contains two integers n and k (1 ≤ n ≤ 1015, 1 ≤ k ≤ 109).
Output
If n has less than k divisors, output -1.
Otherwise, output the k-th smallest divisor of n.
Examples
Input
4 2
Output
2
Input
5 3
Output
-1
Input
12 5
Output
6
Note
In the first example, number 4 has three divisors: 1, 2 and 4. The second one is 2.
In the second example, number 5 has only two divisors: 1 and 5. The third divisor doesn’t exist, so the answer is -1.
题意 很简单 求n的第k大的因子如果不存在k个因子 输出-1
注意到n的范围 直接for 1-n 做会超时
所以改用开方
即求一个数是不是素数常用的 循环1~sqrt(n) 那么这个循环因子的个数需要 *2 (特例见下1)
然后有细节以及问题
1. 假如n=25 以及 其他平方数
2. 假如循环内因子小于k 则需要通过第k因子的 “另一半” 找 (下例)
12 5
6(6 = 12 / 2)
其他见代码
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
#define ll long long
const int maxn = 100000010;
bool vis[maxn];
ll n,k,cnt;
void Find()
{
ll i;
for(i=1; i<=sqrt(n); i++)
{
if(n%i == 0)
{
cnt++;
vis[i] = 1;
}
if(cnt == k)
{
cout<<i<<endl; ///如果能找到 直接输出i
return ;
}
}
if(k > 2*cnt) ///这是k大于因子数的情况
{
cout<<"-1"<<endl;
return ;
}
else
{
ll sum = cnt;
for(i=sqrt(n); i>=1; i--)
{
if(vis[i])
{
if(i != n/i) ///如果是平方数的话 这个判断会去掉不必要的+1计数
{
sum++;
}
}
if(sum == k)
{
cout<<n/i<<endl;
return ;
}
}
}
cout<<-1<<endl; ///如果找不到 对应平方数的情况 因为cnt*2不一定是因子数 (平方数存在)
return ;
}
int main()
{
while(cin>>n>>k)
{
cnt = 0;
memset(vis,0,sizeof(vis));
if(k > n || (n > 2 && k>=n)) ///当k>n时或者说n>2 k>=n 时 一定是-1
{
cout<<"-1"<<endl;
}
else
{
Find();
}
}
return 0;
}