P4318 完全平方数 (莫比乌斯函数,二分,欧拉筛拓展)

53 篇文章 1 订阅
44 篇文章 0 订阅

P4318 完全平方数

题意:
  • 求第 k k k 个既不是完全平方数也不是完全平方正整数倍的数
分析:
  • 对于 1 1 1 个完全平方数 a a a 和它的倍数,将其表示成质因子的幂次的乘积形式: a = 2 x 1 ∗ 3 x 2 ∗ 5 x 3 ∗ . . . a=2^{x_1}* 3^{x_2}*5^{x_3} * ... a=2x13x25x3... 那么必然存在 1 1 1 个质因子的幂次 > 1 >1 >1

    反过来讲,我们要求的即第 k k k 个所有质因子的指数都为 1 1 1 的数(是不是有点熟悉,想一想莫比乌斯函数)

  • 转换问题:求 [ 1 , x ] [1,x] [1,x] 满足条件的数的个数

    考虑容斥,用筛法,将 2 2 , 3 2 , 5 2 , 7 2 . . . 2^2,3^2,5^2,7^2... 22,32,52,72... 和它们的倍数筛掉(类似埃氏筛法)

    埃氏筛会重复筛掉一些数,对于 2 3 2^3 23 3 2 3^2 32 的倍数来说,筛了一遍 6 2 6^2 62 的倍数,因此还要加上 6 2 6^2 62 的倍数

    往下考虑一下,即质因子个数为奇数的筛掉,为偶数的加回来

    a n s = x + ( − 1 ) i 质 因 子 的 个 数 ∗ ( x / i / i ) ans = x+(-1)^{i质因子的个数}*(x/i/i) ans=x+(1)i(x/i/i)

    ( x / i / i ) (x/i/i) (x/i/i) 的系数即莫比乌斯函数

    a n s = ∑ i = 1 x m u ( i ) [ x i 2 ] ans = \sum_{i=1}^{\sqrt x}mu(i)[\frac{x}{i^2}] ans=i=1x mu(i)[i2x]

    然后再用二分判断 [ k , 2 k ] [k,2k] [k,2k] 找到第一个大于 a n s > = k ans>=k ans>=k x x x 即可

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N=1e5+5;
int mu[N], b[N], pri[N];
void mus(int n)
{
    int tot=0; 
    mu[1] = 1;
    for(int i=2;i<n;i++)
    {
        if(!b[i]) mu[i] = -1, pri[++tot] = i;
        for(int j=1;j<=tot && i*pri[j]<n;j++)
        {
            b[i*pri[j]] = 1;
            if(i%pri[j]==0) break ;
            mu[i*pri[j]] = -mu[i];
        }
    }
}
bool check(int k,int n)
{
    int ans=0;
    for(int i=1;i*i<=k;i++)
    {
        ans += mu[i]*(k/i/i);
    }
    return ans >= n;
}

signed main()
{
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    mus(4e4);
    //for(int i=1;i<=100;i++) check(i,1), cout<<i<<' '<<endl;
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        int l=n, r=2*n;
        int ans;
        while(l<=r)
        {
            int mid = l+r>>1;
            if(check(mid, n)) r = mid-1;
            else l = mid+1;
        }
        cout<<l<<endl;
    }
    
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yezzz.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值