zoukankan      html  css  js  c++  java
  • 【*篇】bzoj2440 [中山市选2011]完全平方数

    -题目の传送门-

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

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

    我们要求无平方因子数就要把所有的有平方因字数筛掉, 为了保证不重不漏, 我们考虑容斥.
    我们枚举(1sim sqrt n)中的所有无平方因子数, 将其平方及其平方的倍数删掉.
    这样的话有偶数个质因子的数就被多删了一遍, 我们再将他们加回来.
    我们设容斥系数是(k(i)), 那么

    [ans=sum_{i=1}^{left lfloor sqrt n ight floor}k(i){left lfloor frac n{i^2} ight floor} ]

    而根据上面的分析, 容斥系数(k(i))满足:

    [k(i)=left{egin{matrix} 0, 有平方因子\ 1, 无平方因子, pi(i)是偶数\ -1, 无平方因子, pi(i)是奇数 end{matrix} ight. ]

    非常巧合的是, 这个容斥系数跟(mu)好像是一样的啊...
    所以我们就可以得出

    [ans=sum_{i=1}^{left lfloor sqrt n ight floor}mu(i){left lfloor frac n{i^2} ight floor} ]

    这样预处理一波(mu), 然后每次(O(sqrt n))统计答案即可.
    时间复杂度(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
    ",r);
    	}
    }
    

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

  • 相关阅读:
    跨域踩坑经验总结(内涵:跨域知识科普)
    Nginx location规则匹配
    CentOS 命令
    Centos 修改源
    Ubuntu下获取内核源码
    Ubuntu用户自定义脚本开机启动
    ubuntu 14.04安装x11VNC
    texi格式文件的读取
    更换主机后SSH无法登录的问题
    ubuntu操作系统的目录结构
  • 原文地址:https://www.cnblogs.com/enzymii/p/8421314.html
Copyright © 2011-2022 走看看