• 题解【bzoj2301 [HAOI2011]Problem b】


    Description

    求有多少个数对 ((x,y)) ,满足$ a leq x leq b$ ,(c leq y leq d) ,且 (gcd(x,y) = k)(gcd(x,y))函数为 (x)(y) 的最大公约数。多组询问。(a,b,c,d,k,T leq 50000)

    Solution

    莫比乌斯反演的经典题目QAQ

    首相将问题转化成前缀上的问题。即需要求出 有多少个数对 ((x,y)) ,满足$ 1 leq x leq a$ ,(1 leq y leq b) ,且 (gcd(x,y) = k)。如果能够快速算出来这个,容斥一下就可以求出最后答案。

    考虑这个怎么求,开始推式子。这个东西显然就是

    [sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}[gcd(i,j)=k] ]

    (k) 提出来可得

    [sumlimits_{i=1}^{lfloorfrac{n}{k} floor}sumlimits_{j=1}^{lfloorfrac{m}{k} floor}[gcd(i, j)=1] ]

    然后把后面这个 ([gcd(i,j)=1]) 反演掉,得

    [sumlimits_{i=1}^{lfloorfrac{n}{k} floor}sumlimits_{j=1}^{lfloorfrac{m}{k} floor}sumlimits_{d|gcd(i,j)}mu(d) ]

    (d) 搞到前面来,得到

    [sumlimits_{d=1}^{lfloor frac{n}{k} floor} mu(d)lfloor frac{n}{kd} floorlfloor frac{m}{kd} floor ]

    好了,这个玩意可以预处理出 (mu) 得前缀和然后分块完事。

    Code

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 50000; 
    int k, cnt, p[N + 50], mu[N + 50], flag[N + 50], sum[N + 50]; 
    inline void prework() {
      flag[1] = mu[1] = 1;
      for(int i = 2; i <= N; i++) {
        if(!flag[i]) {
          p[++cnt] = i; mu[i] = -1; 
        } for(int j = 1; j <= cnt && i * p[j] <= N; j++) {
          flag[i * p[j]] = 1;
          if(i % p[j] == 0) {
            mu[i * p[j]] = 0; break; 
          } mu[i * p[j]] = mu[i] * -1; 
        }
      } for(int i = 1; i <= N; i++) sum[i] = sum[i - 1] + mu[i]; 
    }
    inline ll calc(int n, int m) {
      if(n > m) swap(n, m); ll ret = 0; 
      for(int l = 1, r; l <= n / k; l = r + 1) {
        r = min(n / (n / l), m / (m / l)); 
        ret += 1ll * (n / (l * k)) * (m / (l * k)) * (sum[r] - sum[l - 1]); 
      } return ret; 
    }
    int main() {
      int T; prework(); 
      scanf("%d", &T); 
      while(T--) {
        int a, b, c, d; 
        scanf("%d %d %d %d %d", &a, &b, &c, &d, &k);
        printf("%lld
    ", calc(a - 1, c - 1) - calc(b, c - 1) - calc(d, a - 1) + calc(b, d)); 
      }
      return 0; 
    }
    
  • 相关阅读:
    OAF 开发,给组件添加javascript事件
    SQL SERVER占用CPU过高优化
    Winform嵌入CEF(非正常用法)
    多线程——i++的坑
    20150819(i++与++i的思考)
    listView中,checkBox的显示和隐藏
    装箱和拆箱
    虚方法
    [转]关于struct的一些解释与class对比
    提取行政区边界经纬度坐标(高德+百度)
  • 原文地址:https://www.cnblogs.com/acfunction/p/10127599.html
Copyright © 2020-2023  润新知