标签:soj3191 free square 容斥原理 二分 数论
Description
Time Limit: 5000 MS Memory Limit: 65536 KDescription
A positive integer is said to be squarefree if it is divisible by no perfect square larger than 1. For example, the first few squarefree numbers are {1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15, 17, 19, ...}. Can you tell me the K-th ( 1-indexed ) smallest squarefree number.Input
The first line of the input will be a integer to represent the number of test cases. For each test case there is only one line contains only one integer K. ( 1 <= K <= 10^9 ) There is a blank line before each test case.Output
For each test case output the answer on a single line: The K-th smallest squarefree number.Sample Input
6 1 2 7 1000 1234567 1000000000Sample Output
1 2 10 1637 2030745 1644934081Source
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 4000;
const int MAXM = 100100;
int isprime[MAXN];
int prime[MAXN];
int co[MAXM];
int cnt;
void getP() //线性素数筛
{
for(int i = 1; i < MAXN; i++)
isprime[i] = 1;
for(int i = 2; i < MAXN; i++)
{
if(isprime[i])
prime[cnt++] = i;
for(int j = 0; j < cnt&&i*prime[j] < MAXN; j++)
{
isprime[i*prime[j]] = 0;
if(i%prime[j] == 0)
break;
}
}
}
void getCo() //计算素数矩阵
{
for(int i = 2; i < MAXM; i++)
{
co[i] = 1;
int tem = i;
for(int j = 0; prime[j] * prime[j] <= tem; j++)
{
if(tem%prime[j] == 0)
{
co[i] = -co[i]; //找到一个质因子则改变容斥时的加减性
tem /= prime[j];
}
if(tem%prime[j] == 0)
{
co[i] = 0; //不在我们的考虑范围内
break;
}
}
if(tem > 0&&co[i]!=0) co[i] = -co[i];
}
}
int main()
{
int kase, n;
cin >> kase;
getP();
getCo();
while(kase--)
{
cin >> n;
ll l = 1, r = 2e10;
ll mid, tem,ans;
while(l <= r) //二分数,找到第k个数
{
mid = l + (r - l) / 2;
tem = mid;
for(long long i = 2; i*i <= mid; i++)
{
tem = tem + (mid / (i*i))*co[i]; //mid/(i*i)算出在mid范围内有多少个数能被(i*i)整除,再乘上容斥系数
}
if(tem >= n)
{
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
cout << ans << endl;
}
return 0;
}标签:soj3191 free square 容斥原理 二分 数论
原文地址:http://blog.csdn.net/maxichu/article/details/45619531