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;
    }
    
  • 相关阅读:
    Python网络爬虫——Beautiful Soup
    Python网络爬虫——Request
    二叉树结构详解
    哈夫曼树与哈夫曼编码
    树的基本概念
    Linux系统管理—用户和用户组管理
    作为Web开发人员,必须知道的网络协议有哪些?
    编写可靠Linux shell脚本的八个建议
    云计算应用现状与关键技术
    Linux系统如何禁止普通用户切换root?
  • 原文地址:https://www.cnblogs.com/stoorz/p/13725410.html
Copyright © 2011-2022 走看看