[数论] BZOJ2440 完全平方数

6 篇文章 0 订阅
3 篇文章 0 订阅

[数论] BZOJ2440 完全平方数

@(ACM题目)[数论|莫比乌斯函数]

题目链接

二分答案,于是问题转化为求[1,n]中合法的数字的个数。
容斥一下,在全部的n个数字中减去含 p2i1 因子的数个数,再加上含 p2i1p2i2 因子的数的个数,再减去含 p2i1p2i2p2i3 因子的数的个数……再加上含 (1)kp2i1p2i2p2ik 因子的数的个数
注意到此处的 (1)k 恰好是莫比乌斯函数

#include<cstdio>
#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define pb push_back
using namespace std;
typedef long long LL;
const int maxn = 1e7+5;
bool isPrime[maxn];
int primes[maxn], mu[maxn], cnt = 0;//primes数组个数小于maxn;cnt为素数个数
void mobius_sieve() {
    memset(isPrime, true, sizeof isPrime);
    mu[1] = 1;
    cnt= 0;
    for (int i = 2; i < maxn; ++i)
    {
        if (isPrime[i]) primes[cnt++] = i, mu[i] = -1;
        static int d;
        for (int j = 0; j < cnt && (d = i * primes[j]) < maxn; ++j)
        {
            isPrime[d] = false;
            if (i % primes[j]) mu[d] = -mu[i];
            else
            {
                mu[d] = 0;
                break;
            }
        }
    }
}
LL k;
bool check(LL n)
{
    LL tot = n;
    LL sqrtn = sqrt(n);
    for(LL i = 2; i <= sqrtn; i++) tot += mu[i]*(n/(i*i));
    return tot>=k;
}
int main()
{
    mobius_sieve();
    int T;
    cin>>T;
    while(T--)
    {
        cin>>k;
        LL l = 0, r = 2e9+10;
        while(l + 1 < r)
        {
            LL mid = (l+r)>>1;
            if(check(mid)) r = mid;
            else l = mid;
        }
        cout<<r<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值