2440: [中山市選2011]完全平方數
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 966 Solved: 457
[Submit][Status]
Description
小 X 自幼就很喜歡數。但奇怪的是,他十分討厭完全平方數。他覺得這些
數看起來很令人難受。由此,他也討厭所有是完全平方數的正整數倍的數。然而
這絲毫不影響他對其他數的熱愛。
這天是小X的生日,小 W 想送一個數給他作爲生日禮物。當然他不能送一
個小X討厭的數。他列出了所有小X不討厭的數,然後選取了第 K個數送給了
小X。小X很開心地收下了。
然而現在小 W 卻記不起送給小X的是哪個數了。你能幫他一下嗎?
Input
包含多組測試數據。文件第一行有一個整數 T,表示測試
數據的組數。
第2 至第T+1 行每行有一個整數Ki,描述一組數據,含義如題目中所描述。
Output
含T 行,分別對每組數據作出回答。第 i 行輸出相應的
第Ki 個不是完全平方數的正整數倍的數。
Sample Input
1
13
100
1234567
Sample Output
19
163
2030745
HINT
對於 100%的數據有 1 ≤ Ki ≤ 10^9
, T ≤ 50
Source
——分割線——
好吧,這道題是一個裸的莫比烏斯反演,好吧,在做這題之前我只是知道它,完全不曉得這麼神奇!莫比烏斯函數的定義是如果I質因數分解中有任意一個大於1的指數就爲0,否則爲-1。這樣,由這道題的題目和容斥原理,平方數就要加上有奇數個質數平方因子的數,在減去偶數個質數的平方的個數,就是平方數的個數!
具體代碼嘛:
/*Author:WNJXYK*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long
const int Maxn=100000;
LL miu[Maxn+10];
inline void getMiu(){
for (int i=1;i<=Maxn;i++){
LL target=i==1?1:0;
LL delta=target-miu[i];
miu[i]=delta;
for(int j=i+i;j<=Maxn;j+=i){
miu[j]+=delta;
}
}
}
inline LL check(LL n){
LL sn=sqrt(n);
LL Ans=0;
for(int i=1;i<=sn;i++){
Ans+=miu[i]*(n/(i*i));
}
return Ans;
}
inline LL getAns(LL k){
LL left=1,right=k*2+1,mid;
while(left+1<right){
mid=(left+right)/2;
if (check(mid)<k){
left=mid;
}else{
right=mid;
}
}
return right;
}
int T;
int main(){
getMiu();
scanf("%d",&T);
for(int i=1;i<=T;i++){
LL k;
scanf("%lld",&k);
printf("%lld\n",getAns(k));
}
return 0;
}