zoukankan      html  css  js  c++  java
  • bzoj2440

    题目

    小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些
    数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而
    这丝毫不影响他对其他数的热爱。
    这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一
    个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了
    小X。小X很开心地收下了。
    然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?

    题解

    容易想到二分答案,故关键在于求区间[1, n]中不含平方因子的数个数,设这个函数为(f(n))

    假设[1, n]中含有质数(p_1,p_2,...p_k),由容斥原理可得

    [f(n)=n-(lfloorfrac{n}{p_1^2} floor+lfloorfrac{n}{p_2^2} floor+...+lfloorfrac{n}{p_k^2} floor)+(lfloorfrac{n}{p_1^2p_2^2} floor+lfloorfrac{n}{p_1^2p_3^2} floor+...+lfloorfrac{n}{p_1^2p_k^2} floor+...)-(...)+(...)-... ]

    因为分母是平方数,我们可以枚举分母的值,枚举复杂度为(O(sqrt{n}))。那么前面系数怎么求?容易发现,这个系数就是莫比乌斯函数的值!质因数个数为奇数时减 和 质因数个数为偶数时加 真好对应莫比乌斯函数的((-1)^k)。根号下分母不存在含平方质因子的情况,正好对应莫比乌斯函数为零的情况。故有

    [f(n)=sumlimits^{i^2le n}_{i=1}{mu(i)lfloorfrac{n}{i^2} floor} ]

    也可以写成

    [sumlimits^{n}_{i=1}{mu(i)^2}=sumlimits^{i^2le n}_{i=1}{mu(i)lfloorfrac{n}{i^2} floor} ]

    #include <bits/stdc++.h>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
    
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    
    const int N = 1e5 + 10;
    const double eps = 1e-5;
    
    int mu[N];
    int prime[N];
    bool vis[N];
    int cnt;
    
    void init() {
        mu[1] = 1;
        for(int i = 2; i < N; i++) {
            if(!vis[i]) {
                prime[cnt++] = i;
                mu[i] = -1;
            }
            for(int j = 0; j < cnt; j++) {
                int p = prime[j];
                if(i * p > N) break;
                vis[i * p] = 1;
                if(i % p == 0) {
                    mu[i * p] = 0;
                    break;
                }
                mu[i * p] = -mu[i];
            }
        }
    }
    
    ll get(ll n) {
        ll res = 0;
        for(int i = 1; 1ll * i * i <= n; i++) {
            res += mu[i] * (n / (1ll * i * i));
        }
        return res;
    }
    
    
    int main() {
        IOS;
        init();
        int t;
        cin >> t;
        while(t--) {
            int k;
            cin >> k;
            ll l = 1, r = 1800000000;
            while(l <= r) {
                ll mid = (l + r) / 2;
                if(get(mid) >= k) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            cout << l << endl;
        }
    }
    
  • 相关阅读:
    Prometheus监控学习笔记之Prometheus监控简介
    GO语言学习笔记之Linux环境下安装GO语言
    Jetson tx1 安装ROS
    ssh Jetson tk1
    Jetson tk1 安装 Intel 7260 无线网卡驱动
    ubuntu 14.04 软件中心闪退解决方案
    Jetson tk1 刷机后要做的几件事
    Jetson tk1 安装 usbtoserials 驱动(重新刷机)
    usbserials
    ubuntu 14.04 安装 eclipse
  • 原文地址:https://www.cnblogs.com/limil/p/14063968.html
Copyright © 2011-2022 走看看