zoukankan      html  css  js  c++  java
  • 51Nod 欢乐手速场1 C 开心的小Q[莫比乌斯函数]

    tangjz (命题人)
    quailty (测试)
     
    基准时间限制:1 秒 空间限制:131072 KB 分值: 80
    如果一个数字存在一个约数是完全平方数,那么小Q就认为这个数是有趣的。
    小Q喜欢收集有趣的数字,每找到一个有趣的数,小Q就会变得很开心。
    小Q发现12是有趣的,18也是有趣的,它们都是36的约数,而在36的约数中,还有3个数是有趣的,它们是4、9、36。
    小Q很好奇,在a~b里每个数字各有多少个有趣的约数,由于a和b太大了,所以他只想知道这些个数之和是多少。
    例如4有1个有趣的约数,8有2个有趣的约数,9有1个有趣的约数,所以1~10里每个数的有趣约数个数之和是4。
    Input
    输入数据包括2个数:a, b,中间用空格分隔。(1≤a≤b≤10^9)
    Output
    输出a~b里每个数字的有趣约数个数之和。
    Input示例
    1 10
    Output示例
    4


    标解:http://www.51nod.com/contest/problemSolution.html#!problemId=1742


    里面的式子改写一开始一直不明白,稍微有点明白了,说说另一种想的方法吧
    最暴力的是枚举数字再枚举约数看看是不是平方因子数了
    一个简单的优化是枚举约数i,约数i的贡献(倍数的数量)就是[n/i]
    但还是会T
    一个巧妙的想法是我们枚举是几倍,当前枚举的是i倍,那么满足i倍<=n的数字就是<=[n/i],答案加上<=[n/i]的平方因子数的个数,就是标解中最后的式子了
    计算的时候用了两次分块n/(i*i)和n/i做到O(n^2/3)
    然而比只一次分块还慢是什么鬼?sqrt的问题吗
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    inline int read(){
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int a,b;
    bool notp[N];
    int p[N],mu[N];
    void sieve(int n){
        mu[1]=1;
        for(int i=2;i<=n;i++){
            if(!notp[i]) p[++p[0]]=i,mu[i]=-1;
            for(int j=1;j<=p[0]&&i*p[j]<=n;j++){
                notp[i*p[j]]=1;
                if(i%p[j]==0) break;
                mu[i*p[j]]=-mu[i];
            }
        }
        //for(int i=1;i<=n;i++) printf("mu %d %d
    ",i,mu[i]);
        //for(int i=1;i<=n;i++) mu[i]+=mu[i-1];
    }
    //int F(int n){
    //    int _=0,r=0,m=sqrt(n);
    //    for(int i=1;i<=m;i=r+1){
    //        r=n/(n/(i*i));
    //        _+=n/(i*i)*(mu[r]-mu[i-1]);
    //    }
    //    return n-_;
    //}
    int f(int n){
        int _=0,m=sqrt(n);
        for(int i=1;i<=m;i++)
            _+=n/(i*i)*mu[i];
        return n-_;
    }
    ll S(int n){//printf("n %d
    ",n);
        ll ans=0;int r=0;
        for(int i=1;i<=n;i=r+1){
            r=n/(n/i);
            ans+=(r-i+1)*f(n/i);
            //printf("f %d  %d %d  %d
    ",n/i,i,r,f(n/i));
        }
        return ans;
    }
    int main(){
        //freopen("in","r",stdin);
        a=read();b=read();
        sieve(sqrt(b)+1);
        printf("%lld",S(b)-S(a-1));
    }
    一次分块
    
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    inline int read(){
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int a,b;
    bool notp[N];
    int p[N],mu[N];
    void sieve(int n){
        mu[1]=1;
        for(int i=2;i<=n;i++){
            if(!notp[i]) p[++p[0]]=i,mu[i]=-1;
            for(int j=1;j<=p[0]&&i*p[j]<=n;j++){
                notp[i*p[j]]=1;
                if(i%p[j]==0) break;
                mu[i*p[j]]=-mu[i];
            }
        }
        //for(int i=1;i<=n;i++) printf("mu %d %d
    ",i,mu[i]);
        for(int i=1;i<=n;i++) mu[i]+=mu[i-1];
    }
    int F(int n){//printf("F %d
    ",n);
        int _=0,r=0,m=sqrt(n);
        for(int i=1;i<=m;i=r+1){
            r=sqrt(n/(n/(i*i)));//printf("r %d
    ",r);
            _+=n/(i*i)*(mu[r]-mu[i-1]);
        }
        return n-_;
    }
    ll S(int n){//printf("n %d
    ",n);
        ll ans=0;int r=0;
        for(int i=1;i<=n;i=r+1){
            r=n/(n/i);
            ans+=(r-i+1)*F(n/i);
            //printf("F %d  %d %d  %d
    ",n/i,i,r,F(n/i));
        }
        return ans;
    }
    int main(){
        //freopen("in","r",stdin);
        a=read();b=read();
        sieve(sqrt(b)+1);
        printf("%lld",S(b)-S(a-1));
    }
    
    
    



  • 相关阅读:
    5 Things Every Manager Should Know about Microsoft SharePoint 关于微软SharePoint每个经理应该知道的五件事
    Microsoft SharePoint 2010, is it a true Document Management System? 微软SharePoint 2010,它是真正的文档管理系统吗?
    You think you use SharePoint but you really don't 你认为你使用了SharePoint,但是实际上不是
    Introducing Document Management in SharePoint 2010 介绍SharePoint 2010中的文档管理
    Creating Your Own Document Management System With SharePoint 使用SharePoint创建你自己的文档管理系统
    MVP模式介绍
    权重初始化的选择
    机器学习中线性模型和非线性的区别
    神经网络激励函数的作用是什么
    深度学习中,交叉熵损失函数为什么优于均方差损失函数
  • 原文地址:https://www.cnblogs.com/candy99/p/6367375.html
Copyright © 2011-2022 走看看