码迷,mamicode.com
首页 > 其他好文 > 详细

【学术篇】bzoj2440 [中山市选2011]完全平方数

时间:2018-02-06 13:04:24      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:online   printf   代码   log   ref   莫比乌斯反演   一个   display   for   

-题目の传送门-

题目大意: 找到第k个无平方因子数.

看到数据范围很大, 我们要采用比\(O(n)\)还要小的做法.
考虑如果前\(x\)个数中有\(k-1\)个无平方因子数, 而前\(x+1\)个数中有\(k\)个无平方因子数, 那么\(x\)即为所求.
而由某种我不会的方式可以证明出答案是不会超过\(2n\)的, 所以我们可以二分答案.
问题就转化成了求前\(x\)个数中有多少个无平方因子数.

所以我们就要把这些无平方因子数筛一下.
那么首先所有含有平方因子的数我们都不需要考虑, 因为它们的倍数一定会被比他们小的数先筛掉.
而对于剩下的数, 为了方便描述, 我们定义\(\omega(x)\)\(1\sim n\)中有\(x\)个不同质因子的数的个数, 即
\[ \omega(x)=\sum_{i=1,i=\prod_{i=1}^kp_i}^N[k=x] \]
那么根据容斥, 我们就可以得到如下的式子.
\[ ans=n-\frac n{\omega(1)^2}+\frac n{\omega(2)^2}-\frac n{\omega(3)^2}+...=n-\sum_{i=1}^k{\frac n{\omega(i)^2}}*(-1)^{i+1} \]
然后我们发现我们这个好像是莫比乌斯函数??? 恰好包含平方的数的莫比乌斯函数是0, 所以我们整合一波就可以得到
\[ ans=\sum_{i=1}^{\left \lfloor \sqrt n \right \rfloor}\mu(i)*{\left \lfloor \frac n{i^2} \right \rfloor} \]

这样我们枚举\(i\)就可以过啦~
时间复杂度\(O(T*log_2n*\sqrt n)\)

代码:

#include <cstdio>
const int N=45005;
int pr[N],mu[N],tot,n;
bool np[N];
void shai(){
    mu[1]=np[1]=1;
    for(int i=2,k;i<=45000;++i){
        if(!np[i]) pr[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot&&(k=i*pr[j])<=45000;++j){
            np[k]=1;
            if(i%pr[j]==0){mu[k]=0; break;}
            mu[k]=-mu[i];
        }
    }
}
inline bool check(int x,int s=0){
    for(int i=1;i*i<=x;++i)
        s+=x/(i*i)*mu[i];
    return s>=n;
}
int main(){ shai();
    int T; scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int l=1,r=n<<1;
        while(l<r){
            int mid=(1LL*l+r)>>1;
            if(check(mid)) r=mid;
            else l=mid+1;
        }
        printf("%d\n",r);
    }
}

这个题并和莫比乌斯反演没什么关系, 算是莫比乌斯函数的一个小应用吧...

【学术篇】bzoj2440 [中山市选2011]完全平方数

标签:online   printf   代码   log   ref   莫比乌斯反演   一个   display   for   

原文地址:https://www.cnblogs.com/enzymii/p/8421314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!