• bzoj2440: [中山市选2011]完全平方数


    莫比乌斯函数。

    完全平方数的倍数有如下特点。

    1.首先不是质数的完全平方数可以忽略不计,因为它总是一个质数的完全平凡数的倍数。

    2.每个质数i的完全平方数的倍数的个数为(n/(i*i))。

    3.每对质数i,j的完全平方数的倍数已经在i和j时被重复统计了俩次,个数为(n/((i*j)^2))。

    。。。。

    。。。。

    。。。。

    这像什么?

    这就是一个裸的莫比乌斯函数。

    对于每个数i,它对答案的贡献就是μ[i]*(n/(i*i))。

    所以预处理莫比乌斯函数的值,然后二分答案就可以了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int maxn = 100000;
    
    int mu[maxn+10],prime[maxn+10],cnt;
    bool mark[maxn+10];
    
    void predo() {
        mu[1]=1;
        for(int i=2;i<=maxn;i++) {
            if(!mark[i]) {
                mu[i]=-1;
                prime[++cnt]=i;            
            }
            for(int j=1,t;j<=cnt;j++) {
                t=prime[j]*i;
                if(t>maxn) break;
                mark[t]=1;
                if(i%prime[j]==0) {mu[t]=0; break;}
                mu[t]=-mu[i];
            }
        }
    }
    
    long long calc(long long x) {
        long long res=0,t=sqrt(x+0.5);
        for(long long i=1;i<=t;i++) 
            res+=mu[i]*(x/(i*i));    
        return res;
    }
    
    long long n,l,r,mid;
    
    int main() {
        predo();    
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%lld",&n);
            l=1,r=n<<1;
            while(l<r) {
                mid=(l+r)>>1;
                if(calc(mid)>=n) r=mid;
                else l=mid+1;
            }
            printf("%lld
    ",l);
        }
        return 0;
    }
  • 相关阅读:
    树状数组BIT
    KMP算法习题(一本通)
    西大附中集训日志
    图论大杂汇
    [IOI2008/BZOJ1791 岛屿](处理基环树的小技巧&基于bfs树形DP)
    字符串知识清单
    BZOJ刷题列表【转载于hzwer】
    NOIP2018复赛游记
    求极大子矩阵的两种方法
    NOIP2002-字串变换【双向BFS】
  • 原文地址:https://www.cnblogs.com/invoid/p/5599812.html
Copyright © 2020-2023  润新知