• BZOJ 2301 Problem b(莫比乌斯反演+分块优化)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=37166

    题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

    思路:本题使用莫比乌斯反演要利用分块来优化,那么每次询问的复杂度降为2*sqrt(n)+2*sqrt(m)。注意到 n/i ,在连续的k区间内存在,n/i=n/(i+k)。所有对这连续的区间可以一次求出来,不过要先预处理mu的前n项和。

    code:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 const int MAXN = 50005;
     7 
     8 bool check[MAXN];
     9 int primes[MAXN];
    10 int mu[MAXN];
    11 int sum[MAXN];
    12 LL a, b, c, d, k;
    13 
    14 void moblus()
    15 {
    16     memset(check, false, sizeof(check));
    17     mu[1] = 1;
    18     int cnt = 0;
    19     for (int i = 2; i < MAXN; ++i) {
    20         if (!check[i]) {
    21             primes[cnt++] = i;
    22             mu[i] = -1;
    23         }
    24         for (int j = 0; j < cnt; ++j) {
    25             if (i * primes[j] > MAXN) break;
    26             check[i * primes[j]] = true;
    27             if (i % primes[j] == 0) {
    28                 mu[i * primes[j]] = 0;
    29                 break;
    30             } else {
    31                 mu[i * primes[j]] = -mu[i];
    32             }
    33         }
    34     }
    35     sum[0] = 0;
    36     for (int i = 1; i < MAXN; ++i) {
    37         sum[i] = sum[i - 1] + mu[i];
    38     }
    39 }
    40 
    41 LL cal(LL n, LL m)
    42 {
    43     if (n > m) swap(n, m);
    44     n /= k;
    45     m /= k;
    46     LL ret = 0;
    47     for (int i = 1, la = 0; i <= n; i = la + 1) {
    48         la = min(n/(n/i), m/(m/i));
    49         ret += (n / i) * (m / i) * (sum[la] - sum[i - 1]);
    50     }
    51     return ret;
    52 }
    53 
    54 int main()
    55 {
    56     moblus();
    57     int nCase;
    58     scanf("%d", &nCase);
    59     while (nCase--) {
    60         scanf("%lld %lld %lld %lld %lld", &a, &b, &c, &d, &k);
    61         LL ans = cal(b, d) - cal(a - 1, d) - cal(b, c - 1) + cal(a - 1, c - 1);
    62         printf("%lld
    ", ans);
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    Mybatis批量插入,是否能够返回id列表
    SVN和Git代码管理小结
    SVN和Git代码管理小结
    Spring异步执行(@Async)2点注意事项
    Spring异步执行(@Async)2点注意事项
    2015年工作中遇到的问题101-110
    Codeforces 263B. Appleman and Card Game
    Codeforces 263A. Appleman and Easy Task
    HDU 482 String
    字符串hash-BKDRHash
  • 原文地址:https://www.cnblogs.com/ykzou/p/4793714.html
Copyright © 2020-2023  润新知