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;
    }
    
  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/stoorz/p/13725410.html
Copyright © 2011-2022 走看看