SOJ 3191 Free square 容斥原理+二分

题目连接:http://zuojie.3322.org:88/soj/problem.action?id=3191

Description

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

1000000000

Sample Output

1

2

10

1637

2030745

1644934081

用360浏览器看代码可能看到的是乱码,建议使用搜狗浏览器,邪恶的CSDN,改版后让我非常窝火。。

好了,扯远了,我讲一下这个题的思路吧。这个题也是传说中的windy教主出的。。非常霸气的一道题目。我刚开始做的时候大体思路还是正确的,就是二分+容斥。

可是大量的细节和模拟能力不足导致迟迟不能AC。后来参考了下别人的思路和代码,自己理解后再次敲了下,轻松AC了。

我们可以预先处理出250以下的素数,然后通过这一些素数我们选出2-50000以内符合要求的数。并且判断每一个数的质因数个数是奇数还是偶数(以后用来容斥)

最后是利用二分答案来实现的。

详见代码:

#include<stdio.h> #include<string.h> #define MAXN 50000 typedef long long LL; LL a[MAXN]; LL prime[250]; bool flag[250]; void init() { LL i,j,num=0,k; for(i=2;i<250;i++) { if(!flag[i]) { prime[num++]=i; for(j=i*i;j<250;j=j+i) flag[j]=true; } } for(i=2;i<MAXN;i++) { a[i]=1; k=i; for(j=0;prime[j]*prime[j]<=k;j++) { if(k%prime[j]==0) { a[i]=-a[i]; k=k/prime[j]; if(k%prime[j]==0) { a[i]=0; break; } } } if(k>1&&a[i]!=0) a[i]=-a[i]; } } void solve(LL n) { LL left,right,mid,ans,i; left=1,right=1644934081; while(left<=right) { mid=(left+right)/2; ans=mid; for(i=2;i*i<=mid;i++) ans=ans+(mid/(i*i))*a[i]; if(ans>=n) right=mid-1; else left=mid+1; } printf("%lld\n",left); } int main() { LL t,n; init(); while(scanf("%lld",&t)!=EOF) { while(t--) { scanf("%lld",&n); solve(n); } } return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值