zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x37莫比乌斯函数 ZAP

    题目链接:https://www.acwing.com/problem/content/217/

     通过容斥原理可以先算是1的倍数的所有数,然后将2,3,5,7倍数的数删掉,其中是2的倍数又是3的倍数的删了两次,所以要加回来,这时候可以发现,系数与莫比乌斯函数是对应的。只算是单个质因子的倍数的数,所以跟莫比乌斯函数有联系。求[a/x]*[b/x]时可以利用性质,将[1,min(a,b)]这段分成不超过O(sqrt(a)+sqrt(b))的小段,对每段求相应的莫比乌斯函数的和,所以可以预处理出莫比乌斯函数的前缀和。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 50010;
    int miu[maxn];
    bool vis[maxn];
    void get_miu(int n){//求莫比乌斯函数的前缀和 
        for(int i=1;i<=n;i++){
            miu[i]=1;    
            vis[i]=0;
        }
        for(int i=2;i<=n;i++){
            if(vis[i])continue;
            miu[i]=-1;//质数
            for(int j=2*i;j<=n;j+=i){
                vis[j]=1;
                if((j/i)%i==0)miu[j]=0;//分解质因数之后不是单个的 
                else miu[j]*=-1;//多增加了一个质因数项 
            } 
        }
        for(int i=1;i<=n;i++)miu[i]+=miu[i-1]; 
    }
    void Zap(){
        int a,b,k;
        scanf("%d%d%d",&a,&b,&k);
        a/=k;
        b/=k;
        int ans=0;
        if(a>b)swap(a,b);
        for(int x=1,gx;x<=a;x=gx+1){
            gx=min(a/(a/x),b/(b/x));
            ans+=(miu[gx]-miu[x-1])*(a/x)*(b/x);
        }
        printf("%d
    ",ans);
    }
    int main(){
        get_miu(50005);
        int n;
        cin>>n;
        while(n--)Zap();
        return 0;
    }
  • 相关阅读:
    pspc命令使用(转)
    NSArray数组的使用常用方法(转)
    css兼容的问题 持续更新
    关于memcache
    drupal7 学习笔记(持续更新中...)
    JavaScript的继承 转载
    浏览器的缓存机制
    我的js单例模式
    javascript运行机制
    javascrpt绑定事件之匿名函数
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13281537.html
Copyright © 2011-2022 走看看