• HDU 1695 莫比乌斯反演


    题目大意:

    从1~b中取一个数作为x , 1~d中取一个数作为y

    令gcd(x,y) = k 的取法有多少种

    这里我们可以用莫比乌斯函数来解决问题

    这里用到的公式是[gcd(x,y)==1] = Σ(del|gcd(x,y))mu(del)

    Σ(1<=x<=b)Σ(1<=y<=d)[gcd(x,y)==k]

    = Σ(1<=x<=b/k)Σ(1<=y<=d/k)[gcd(x,y)==1]

    = Σ(1<=x<=b/k)Σ(1<=y<=d/k) Σ(del|gcd(x,y)) mu(del)

    =Σ(1<=x<=b/k & del|x)Σ(1<=y<=d/k & del|y)  mu(del)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 #define ll long long
     7 #define N 100010
     8 int mu[N] , prime[N] ;
     9 bool check[N];
    10 
    11 void getMu(int n)
    12 {
    13     memset(check , 0 , sizeof(check));
    14     mu[1] = 1;
    15     int tot = 0;
    16     for(int i=2 ; i<=n ; i++){
    17         if(!check[i]){
    18             prime[tot++]=i;
    19             mu[i] = -1;
    20         }
    21         for(int j=0 ; j<tot ; j++){
    22             if(i*prime[j]>n) break;
    23             check[i*prime[j]] = true;
    24             if(i % prime[j] == 0){
    25                 mu[i*prime[j]] = 0;
    26                 break;
    27             }else{
    28                 mu[i*prime[j]] = -mu[i];
    29             }
    30         }
    31     }
    32 }
    33 
    34 int main()
    35 {
    36     int a , b , c , d , k , T , cas=0;
    37     scanf("%d" , &T);
    38     getMu(100000);
    39     while(T--)
    40     {
    41         scanf("%d%d%d%d%d" , &a , &b , &c , &d , &k);
    42         if(k == 0){
    43              printf("Case %d: 0
    " , ++cas);
    44              continue;
    45         }
    46         a/=k , b/=k , c/=k , d/=k;
    47         int maxn = b;
    48         if(b<d){
    49             int t=b;
    50             b=d , d=t;
    51             maxn = b;
    52         }
    53         ll ans = 0;
    54         for(int i=1 ; i<=maxn ; i++){
    55             int t1 = b/i , t2=d/i;
    56             ans = ans+(ll)t1*t2*mu[i];
    57         }
    58 
    59         //计算重复的
    60         ll tmp = 0;
    61         for(int i=1 ; i<=maxn ; i++){
    62             int t1 = d/i , t2 = d/i;
    63             tmp = tmp+(ll)t1*t2*mu[i];
    64         }
    65         ans = ans - (tmp-1)/2;
    66         printf("Case %d: %lld
    " , ++cas , ans);
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    2015 11月30日 一周工作计划与执行
    2015 11月23日 一周工作计划与执行
    js 时间加减
    unix高级编程阅读
    2015 11月16日 一周工作计划与执行
    2015 11月9日 一周工作计划与执行
    python2与python3差异,以及如何写两者兼容代码
    property属性
    js刷新页面函数 location.reload()
    常用表单验证
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4422861.html
Copyright © 2020-2023  润新知