zoukankan      html  css  js  c++  java
  • 完全平方数 HYSBZ

    题意:

    求出第 (ki) 个不是完全平方数的整数倍的数。((1) 是第一个)
    数据范围:(1 ≤ Ki ≤ 10^9,T ≤ 50)

    分析:

    首先可以想到,用容斥定理来求。但实际上,完全平方数有很多,不可能一个一个地枚举出来,然后奇加偶减。
    对于 (sqrt{n}) 以内的素数集合:(s)(n) 以内的不含完全平方数因子的数的个数:
    (ans=frac{n}{1*1}-frac{n}{2*2}-frac{n}{3*3}-frac{n}{5*5}+frac{n}{6*6}...)
    显然,偶数个质数平方对于答案的贡献就是正的,否则是负;如果不是若干个互异质数的乘积,那么对答案没有影响,因为它们已经被所含的质数处理过。
    所以:

    [ans=sum_{i=1}^{sqrt{n}}{mu[i]*frac{n}{i*i}} ]

    结合二分即可找出符合条件的数。
    注意
    1.二分时,是找到第一个满足条件的数,所以在改变区间时要注意写法;
    2.二分时,(l+r) 会爆 (int)

    代码:

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    int mu[N];
    vector<int>prime;
    bool vis[N];
    void read(int &x)
    {
        x=0;
        int f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    void init()
    {
        mu[1]=1;
        memset(vis,0,sizeof(vis));
        for(int i=2;i<=N-5;i++)
        {
            if(!vis[i])
            {
                prime.pb(i);
                mu[i]=-1;
            }
            for(int j=0;j<prime.size()&&1LL*prime[j]*i<=N-5;j++)
            {
                vis[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    mu[i*prime[j]]=0;
                    break;
                }
                else
                    mu[i*prime[j]]=-mu[i];
            }
        }
    }
    ll solve(int n)
    {
        ll ans=0;
        for(int i=1;1LL*i*i<=n;i++)
            ans+=(mu[i]*n/(i*i));
        return ans;
    }
    int main()
    {
        int t,k;
        init();
        read(t);
        while(t--)
        {
            read(k);
            ll l=1,r=2*k+5;
            while(l<=r)
            {
                ll mid=(l+r)>>1;
                ll t=solve(mid);
                if(t<k)
                    l=mid+1;
                else
                    r=mid-1;
            }
            printf("%lld
    ",l);
        }
        return 0;
    }
    
    
  • 相关阅读:
    86. Partition List
    328. Odd Even Linked List
    19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)
    24. Swap Nodes in Pairs
    2. Add Two Numbers(2个链表相加)
    92. Reverse Linked List II(链表部分反转)
    109. Convert Sorted List to Binary Search Tree
    138. Copy List with Random Pointer
    为Unity的新版ugui的Prefab生成预览图
    ArcEngine生成矩形缓冲区
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12537070.html
Copyright © 2011-2022 走看看