• HDU 1695 GCD(欧拉函数+容斥原理)


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

    题意:x位于区间[a, b],y位于区间[c, d],求满足GCD(x, y) = k的(x, y)有多少组,不考虑顺序。

    思路:a = c = 1简化了问题,原问题可以转化为在[1, b/k]和[1, d/k]这两个区间各取一个数,组成的数对是互质的数量,不考虑顺序。我们让d > b,我们枚举区间[1, d/k]的数i作为二元组的第二位,因为不考虑顺序我们考虑第一位的值时,只用考虑小于i的情况。对于i<=b,因为第一位[1, i]都可以取到,互质的对数就是欧拉函数值。现在考虑i位于[b/k+1, d/k],此时我们要用b - [1, b/k]中与i不互质数的个数,那么关键问题就是求[1, b/k]中与i不互质数的个数,我们将i分解质因子,在b/k范围内每个因子的倍数肯定与i不互质。设i的素因子分别的p1,p2...pk,则1..b/k中p1的倍数组成集合A1,p2的倍数组成集合A2,p3到A3.....pk到Ak, 由于集合中会出现重复的元素,所以用容斥原理来求A1并A2并A3.....并Ak的元素的数的个数。区间中与i不互质的个数 = (区间中i的每个质因数的倍数个数)-(区间中i的每两个质因数乘积的倍数)+(区间中i的每3个质因数的乘积的倍数个数)-(区间中i的每4个质因数的乘积)+ ...

    code:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int MAXN = 100005;
     7 
     8 LL phi[MAXN];       // 欧拉函数的和
     9 int num[MAXN];      // 素因子个数
    10 int p[MAXN][20];    // 素因子
    11 
    12 void init()
    13 {
    14     memset(phi, 0, sizeof(phi));
    15     memset(num, 0, sizeof(num));
    16     phi[1] = 1L;
    17     for (int i = 2; i < MAXN; ++i) {
    18         if (!phi[i]) {
    19             for (int j = i; j < MAXN; j += i) {
    20                 if (!phi[j]) phi[j] = j;
    21                 phi[j] = phi[j] * (i - 1) / i;
    22                 p[j][num[j]++] = i;
    23             }
    24         }
    25         phi[i] += phi[i - 1];
    26     }
    27 }
    28 
    29 LL dfs(int idx, int b, int now) // 求不大于b的数中,与now不互质的数的个数;
    30 {
    31     LL ret = 0;
    32     for (int i = idx; i < num[now]; ++i) { // 容斥原理来求A1并A2并A3.....并Ak的元素的数的个数
    33         ret += b / p[now][i] - dfs(i + 1, b / p[now][i], now);
    34     }
    35     return ret;
    36 }
    37 
    38 
    39 int main()
    40 {
    41     init();
    42     int nCase;
    43     scanf("%d", &nCase);
    44     for (int cas = 1; cas <= nCase; ++cas) {
    45         int a, b, c, d, k;
    46         scanf("%d %d %d %d %d", &a, &b, &c, &d, &k);
    47         if (k == 0) {
    48             printf("Case %d: 0
    ", cas);
    49             continue;
    50         }
    51         if (b > d) swap(b, d);
    52         b /= k;
    53         d /= k;
    54         LL ans  = phi[b];
    55         for (int i = b + 1; i <= d; ++i) {
    56             ans += b - dfs(0, b, i); // 求不大于b的数中,与i不互质的数的个数
    57         }
    58         printf("Case %d: %lld
    ", cas, ans);
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    SpringCloud学习系列之四-----配置中心(Config)使用详解
    阿里云Docker镜像仓库(Docker Registry)
    阿里云Docker镜像加速
    Docker安装(yum方式 centos7)
    Docker Nginx安装(centos7)
    Dockerfile文件详解
    mysql 开发进阶篇系列 6 锁问题(事务与隔离级别介绍)
    mysql 开发进阶篇系列 5 SQL 优化(表优化)
    mysql 开发进阶篇系列 4 SQL 优化(各种优化方法点)
    sql server 性能调优之 资源等待PAGELATCH
  • 原文地址:https://www.cnblogs.com/ykzou/p/4781364.html
Copyright © 2020-2023  润新知