zoukankan      html  css  js  c++  java
  • 【洛谷P4318】完全平方数

    题目

    题目链接:https://www.luogu.com.cn/problem/P4318
    小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。

    这天是小 X 的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一个小 X 讨厌的数。他列出了所有小 X 不讨厌的数,然后选取了第 \(k\) 个数送给了小X。小 X 很开心地收下了。

    然而现在小 W 却记不起送给小 X 的是哪个数了。你能帮他一下吗?

    思路

    即求第 \(k\) 个不含完全平方数因子的数字。
    二分转换为判定性问题,转化成求不超过 \(n\) 有多少个不含完全平方因子的数。
    \(f(i)\) 表示 \(i\) 个不同质数的乘积的平方的数字个数,那么答案为 \(\sum^{\sqrt{n}}_{i=1}(-1)^{i+1}f(i)\)
    发现系数即为 \(\mu(i)\)。所以线性筛出 \(\mu\) 即可。
    时间复杂度 \(O(T\log A\sqrt{A})\)。其中 \(A\) 为二分上界。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1000010;
    int Q,n,m,prm[N],mu[N];
    bool v[N];
    
    void findprm(int n)
    {
    	mu[1]=1;
    	for (int i=2;i<=n;i++)
    	{
    		if (!v[i])
    		{
    			prm[++m]=i;
    			mu[i]=-1;
    		}
    		for (int j=1;j<=m;j++)
    		{
    			if (i>n/prm[j]) break;
    			v[i*prm[j]]=1; mu[i*prm[j]]=-mu[i];
    			if (!(i%prm[j]))
    			{
    				mu[i*prm[j]]=0;
    				break;
    			}
    		}
    	}
    }
    
    ll count(ll mid)
    {
    	ll cnt=0;
    	for (int i=1;1LL*i*i<=mid;i++)
    		cnt+=mid/i/i*mu[i];
    	return cnt;
    }
    
    int main()
    {
    	findprm(N-10);
    	scanf("%d",&Q);
    	while (Q--)
    	{
    		scanf("%d",&n);
    		ll l=1,r=10000000000LL,mid;
    		while (l<=r)
    		{
    			mid=(l+r)>>1;
    			if (count(mid)>=n) r=mid-1;
    				else l=mid+1;
    		}
    		printf("%lld\n",r+1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Handler详细说明系列(六)——View的post()详解
    2013年6月17日星期一
    2013年6月16日星期日
    线程管理四种方法
    java 线程 ProducerAndConsumer
    POJ 2948 DP
    Java的递归算法
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
    网络安全审查制度即将推出 手机App安全加密成必定趋势
    递归算法浅谈
  • 原文地址:https://www.cnblogs.com/stoorz/p/13725410.html
Copyright © 2011-2022 走看看