zoukankan      html  css  js  c++  java
  • uva11426(莫比乌斯反演)

    传送门:GCD Extreme (II)

    题意:给定n(n<=4000000),求G

    G=0

    for(int i=1;i<n;i++)

    for(int j=i+1;j<=n;j++)

    G+=gcd(i,j).  

    分析:这题本来应该欧拉函数预处理来解决,不过尝试一下莫比乌斯反演,没想到也AC了,复杂度O(nlog(n)),应该是题目100case中大数据不多,不然会超时吧。

    设F(n)表示gcd(x,y)==n的倍数所有gcd之和,f(n)表示gcd(x,y)==n的所有gcd之和,那么反演有:

    f(1)=mu(1)*F(1)+mu(2)*F(2)+...+mu(n)*F(n).

    f(2)=mu(1)*F(2)+mu(2)*F(4)+...+mu(n/2)*F(n).

    ......

    F(d)=(n/i)*(n/i-1)/2*d(其中i%d==0).

    用筛素数的方法就可求出所有的f(i)了。

    #pragma comment(linker,"/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <limits.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 100000000
    #define inf 0x3f3f3f3f
    #define eps 1e-6
    #define N 4000000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define PII pair<int,int>
    using namespace std;
    inline int read()
    {
        char ch=getchar();int x=0,f=1;
        while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    bool vis[N+5];
    int mu[N+5],prime[N+5],sum[N+5],cnt[N+5];
    void Mobius()
    {
        memset(vis,false,sizeof(vis));
        mu[1]=1;
        int tot=0;
        for(int i=2;i<=N;i++)
        {
            if(!vis[i])
            {
                prime[tot++]=i;
                mu[i]=-1;
            }
            for(int j=0;j<tot;j++)
            {
                if(i*prime[j]>N)break;
                vis[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    mu[i*prime[j]]=0;
                    break;
                }
                else
                {
                    mu[i*prime[j]]=-mu[i];
                }
            }
        }
    }
    
    int main()
    {
        int n;
        Mobius();
        while(scanf("%d",&n),n)
        {
           LL ans=0;
           for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j+=i)
            ans+=(LL)mu[j/i]*(n/j)*(n/j-1)/2*i;
           printf("%lld
    ",ans);
        }
    }
    View Code

     

  • 相关阅读:
    Codeforces Gym 100571A A. Cursed Query 离线
    codeforces Gym 100500 J. Bye Bye Russia
    codeforces Gym 100500H H. ICPC Quest 水题
    codeforces Gym 100500H A. Potion of Immortality 简单DP
    Codeforces Gym 100500F Problem F. Door Lock 二分
    codeforces Gym 100500C D.Hall of Fame 排序
    spring data jpa 创建方法名进行简单查询
    Spring集成JPA提示Not an managed type
    hibernate配置文件中的catalog属性
    SonarLint插件的安装与使用
  • 原文地址:https://www.cnblogs.com/lienus/p/4298534.html
Copyright © 2011-2022 走看看