• hdu1695 GCD(莫比乌斯入门题)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695

    题意:

     给出n、m、k ,求出1<=x<=n, 1<=y<=m 且gcd(x,y) == k 的(x,y)的对数

    解析:

    显然就是求 [1,n/k] 与 [1, m/k]有多少数对的最大公约数是1

    莫比乌斯入门题

    我们设

        为满足的对数

        为满足的对数

     那么,很显然,反演后得到

    我们所需要的答案便是  f(1) = i=1µ(i)*(n/i)*(m/i)  ,求解这个式子我们可以分块求和,复杂度为O(√n)。

    最后注意由于题目要求,需要将重复的去掉。

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 const int maxn=100010;
     8 
     9 int vis[maxn];
    10 int prime[maxn];
    11 int cnt;
    12 int mu[maxn];
    13 int sum[maxn];
    14 
    15 void init()
    16 {
    17     memset(vis,0,sizeof(vis));
    18     cnt=0;
    19     mu[1]=1;
    20     for(int i=2;i<maxn;i++)
    21     {
    22         if(!vis[i])
    23         {
    24             prime[cnt++]=i;
    25             mu[i]=-1;
    26         }
    27         for(int j=0;j<cnt&&i*prime[j]<maxn;j++)
    28         {
    29             vis[i*prime[j]]=1;
    30             if(i%prime[j])
    31                 mu[i*prime[j]]=-mu[i];
    32             else
    33             {
    34                 mu[i*prime[j]]=0;
    35                 break;
    36             }
    37         }
    38     }
    39     sum[0]=0;
    40     for(int i=1;i<maxn;i++)
    41         sum[i]=sum[i-1]+mu[i];
    42 }
    43 
    44 int main()
    45 {
    46     int a,b,c,d,k;
    47     init();
    48     int T,ca=1;
    49     scanf("%d",&T);
    50     while(T--)
    51     {
    52         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
    53         printf("Case %d: ",ca++);
    54         if(k==0)
    55         {
    56             printf("0
    ");
    57             continue;
    58         }
    59         b=b/k;
    60         d=d/k;
    61         if(b>d)
    62             swap(b,d);
    63         long long ans1=0;
    64         int last;
    65         for(int i=1;i<=b;i=last+1)
    66         {
    67             last=min(b/(b/i),d/(d/i));
    68             ans1+=(long long)(sum[last]-sum[i-1])*(b/i)*(d/i);
    69         }
    70         long long ans2=0;
    71         for(int i=1;i<=b;i=last+1)
    72         {
    73             last=b/(b/i);
    74             ans2+=(long long)(sum[last]-sum[i-1])*(b/i)*(b/i);
    75         }
    76         long long ans=ans1-ans2/2;
    77         printf("%lld
    ",ans);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    弹性网卡支持私网多IP
    微服务浪潮中,程序猿如何让自己 Be Cloud Native
    Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力
    如何更高效的管理原生微服务应用
    如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes
    PHP flock文件锁
    MySQL锁(MyISAM和InnoDB)
    汽车操作系统革命:封闭还是开源?
    采集百度top500歌曲,python2.7.2
    关于revision 的cover letter
  • 原文地址:https://www.cnblogs.com/yaoyueduzhen/p/6028634.html
Copyright © 2020-2023  润新知