zoukankan      html  css  js  c++  java
  • Bzoj 2818: Gcd 莫比乌斯,分块,欧拉函数,线性筛

    2818: Gcd

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 3241  Solved: 1437
    [Submit][Status][Discuss]

    Description

    给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
    数对(x,y)有多少对.

    Input

    一个整数N

    Output

    如题

    Sample Input

    4

    Sample Output

    4

    HINT

    hint

    对于样例(2,2),(2,4),(3,3),(4,2)


    1<=N<=10^7

    Source

    湖北省队互测

    题解:

    莫比乌斯函数或欧拉函数。

    莫比乌斯函数详见 Popoqqq的课件 (Orz Po姐)

    之后就自己推公式吧。。。

    莫比乌斯函数:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define MAXN 10000010
     5 int prime[670010],mu[MAXN],qz[MAXN],tot,N;
     6 bitset<MAXN> vis;
     7 int read()
     8 {
     9     int s=0,fh=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    12     return s*fh;
    13 }
    14 void getmu()
    15 {
    16     int i,j;
    17     mu[1]=1;
    18     tot=0;
    19     for(i=2;i<=N;i++)
    20     {
    21         if(vis[i]==0)
    22         {
    23             prime[++tot]=i;
    24             mu[i]=-1;
    25         }
    26         for(j=1;j<=tot&&prime[j]*i<=N;j++)
    27         {
    28             vis[prime[j]*i]=1;
    29             if(i%prime[j]==0)
    30             {
    31                 mu[i*prime[j]]=0;
    32                 break;
    33             }
    34             mu[i*prime[j]]=-mu[i];
    35         }
    36     }
    37 }
    38 void Qz()
    39 {
    40     for(int i=1;i<=N;i++)qz[i]=qz[i-1]+mu[i];
    41 }
    42 LL calc(int n)
    43 {
    44     int d,pos;
    45     LL sum=0;
    46     for(d=1;d<=n;d=pos+1)
    47     {
    48         pos=n/(n/d);
    49         sum+=(LL)(n/d)*(n/d)*(qz[pos]-qz[d-1]);
    50     }
    51     return sum;
    52 }
    53 int main()
    54 {
    55     int i;
    56     LL ans=0;
    57     N=read();
    58     getmu();
    59     Qz();
    60     for(i=1;i<=tot&&prime[i]<=N;i++)ans+=calc(N/prime[i]);
    61     printf("%lld",ans);
    62     fclose(stdin);
    63     fclose(stdout);
    64     return 0;
    65 }
    View Code

     欧拉函数:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define MAXN 10000010
     4 #define LL long long
     5 bitset<MAXN> vis;
     6 int N,prime[670010],phi[MAXN],tot;
     7 LL qz[MAXN];
     8 int read()
     9 {
    10     int s=0,fh=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
    13     return s*fh;
    14 }
    15 void geteular()
    16 {
    17     int i,j;
    18     phi[1]=1;tot=0;
    19     for(i=2;i<=N;i++)
    20     {
    21         if(vis[i]==0)
    22         {
    23             prime[++tot]=i;
    24             phi[i]=i-1;
    25         }
    26         for(j=1;j<=tot&&prime[j]*i<=N;j++)
    27         {
    28             vis[prime[j]*i]=1;
    29             if(i%prime[j]==0)
    30             {
    31                 phi[prime[j]*i]=phi[i]*prime[j];
    32                 break;
    33             }
    34             phi[prime[j]*i]=phi[prime[j]]*phi[i];
    35         }
    36     }
    37 }
    38 void Qz()
    39 {
    40     qz[0]=qz[1]=0;
    41     for(int i=2;i<=N;i++)qz[i]=qz[i-1]+phi[i];
    42 }
    43 int main()
    44 {
    45     int i,n;
    46     LL ans=0;
    47     N=read();
    48     geteular();
    49     Qz();
    50     for(i=1;i<=tot;i++)
    51     {
    52         n=N/prime[i];
    53         ans+=(qz[n]*2+1);
    54     }
    55     printf("%lld",ans);
    56     fclose(stdin);
    57     fclose(stdout);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    Eclipse svn插件包
    最新版STS因为JDK版本太低无法启动的解决办法
    maven 项目无法发布,无法编译的解决办法
    maven依赖本地非repository中的jar包
    微信公众平台开发(2)-消息封装
    微信公众平台开发(4)-自定义菜单
    限制必须使用微信打开网页
    移动设备页面自适应
    微信公众平台开发(5)-上传下载多媒体文件
    微信公众平台开发(3)-回复消息
  • 原文地址:https://www.cnblogs.com/Var123/p/5284550.html
Copyright © 2011-2022 走看看