zoukankan      html  css  js  c++  java
  • hdu 1965 (莫比乌斯函数 莫比乌斯反演)

    GCD

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9942    Accepted Submission(s): 3732


    Problem Description
    Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.
    Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.

    Yoiu can assume that a = c = 1 in all test cases.
     
    Input
    The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases.
    Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
     
    Output
    For each test case, print the number of choices. Use the format in the example.
     
    Sample Input
    2 1 3 1 5 1 1 11014 1 14409 9
     
    Sample Output
    Case 1: 9 Case 2: 736427
    Hint
    For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
     
    Source
     
    Recommend
    wangye   |   We have carefully selected several similar problems for you:  1689 1690 1693 1691 1698 

    此题算是莫比乌斯反演的经典题。
    虽然上面说了把a和c当作1 ,但我们还是把它当做任意数来做。
    对于求(a,b) (c,d)上对应的最大公约数为k这类题,先用容斥原理分为四种:(1,b)与(1,d);(1,c-1)与(1,b);(1,a-1)与(1,d);
    对于每种情况,假设是(1,n)与(1,m)这两个区间(n<m)。
      那这两个区间gcd(x,y)>=k的有(n/k)*(m/k)个。
      若要求最大公约数为k,那么求得便是(n/k)与(m/k)中互质的数的个数。
      接下来就用莫比乌斯函数求这些互质的数的个数了。
      其中我还加入了分段优化。
         最后一步就是去重了,题目说想 G(x,y)==G(y,x),所以要把(a,b) (c,d)里重叠的部分多余的去掉。
      具体【传送门
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #define clr(x) memset(x,0,sizeof(x))
     6 #define LL long long
     7 using namespace std;
     8 int prime[100010],inf[100010],mu[100010],sum[100010];
     9 long long solve(int n,int m);
    10 void mobius();
    11 int main()
    12 {
    13     int T;
    14     scanf("%d",&T);
    15     int a,b,c,d,k,minx,maxx;
    16     LL  ans;
    17     mobius();
    18     for(int ii=1;ii<=T;ii++)
    19     {
    20         scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
    21          if(k == 0)
    22          {
    23              printf("Case %d: 0
    ",ii);
    24              continue;
    25          }
    26         ans=solve(b/k,d/k) - solve((a-1)/k,d/k) - solve(b/k,(c-1)/k) + solve((a-1)/k,(c-1)/k);
    27         if((maxx=max(a,c))<(minx=min(b,d)))
    28         ans=ans-(solve(minx/k,minx/k)-solve((maxx-1)/k,minx/k)*2+solve((maxx-1)/k,(maxx-1)/k))/2;
    29         printf("Case %d: %lld
    ",ii,ans);
    30     }
    31     return 0;
    32 }
    33 void mobius()
    34 {
    35     clr(inf);
    36     clr(prime);
    37     clr(sum);
    38     clr(mu);
    39     mu[1] = 1;
    40     inf[1]=inf[0]=1;
    41     int tot = 0;
    42     for(int i = 2; i <= 100000; i++)
    43     {
    44         if( !inf[i] )
    45         {
    46             prime[tot++] = i;
    47             mu[i] = -1;
    48         }
    49         for(int j = 0; j < tot; j ++)
    50         {
    51             if( i * prime[j] > 100000) break;
    52             inf[i * prime[j]] = true;
    53             if( i % prime[j] == 0)
    54             {
    55                 mu[i * prime[j]] = 0;
    56                 break;
    57             }
    58             else
    59             {
    60                 mu[i * prime[j]] = -mu[i];
    61             }
    62         }
    63     }
    64     for(int i = 1;i <= 100000;i++)
    65         sum[i] = sum[i-1] + mu[i];
    66 }
    67 LL solve(int n,int m)
    68 {
    69     LL ans = 0;
    70     if(n > m)swap(n,m);
    71     for(int i = 1, la = 0; i <= n; i = la+1)
    72     {
    73         la = min(n/(n/i),m/(m/i));
    74         ans += (LL)(sum[la] - sum[i-1])*(n/i)*(m/i);
    75     }
    76     return ans;
    77 }
  • 相关阅读:
    html5+css3酷炫音频播放器代码
    js/html/css做一个简单的图片自动(auto)轮播效果//带注释
    gVIM+zencoding快速开发HTML/CSS/JS(适用WEB前端)
    使用libcurl,根据url下载对应html页面
    CSS+HTML+JQuery简单菜单
    【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)
    【CodeForces727E/CF727E】Games on a CD (字符串哈希)
    【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)
    【BZOJ2565】最长双回文串 (Manacher算法)
    【洛谷2926/BZOJ1607】[USACO08DEC]Patting Heads拍头(筛法)
  • 原文地址:https://www.cnblogs.com/wujiechao/p/5897696.html
Copyright © 2011-2022 走看看