• Problem b[HAOI2011]


    题目描述

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

    题解

    莫比乌斯反演

    我们可以用二维前缀和的思想,我们设

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

    那答案应为

    (f(b,d)-f(b,c-1)-f(a-1,d)+f(a-1,c-1))

    接下来看看(f(n,m))怎么求:

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

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

    使用莫比乌斯反演

    (=sumlimits_{i=1}^{n/k} sumlimits_{j=1}^{m/k} sumlimits_{d|gcd(i,j)}mu(d))

    (d)放到前面枚举,设(i=xd, j=yd)

    (=sumlimits_{d} mu(d) * sumlimits_{x=1}^{n/kd} sumlimits_{y=1}^{m/kd} 1)

    (=sumlimits_{d} mu(d) * lfloor frac{n}{kd} floor * lfloor frac{m}{kd} floor)

    预处理(mu(d))的前缀和,使用除法分块即可做到时间复杂度(O(sqrt{n}))

    总时间复杂度(O(nsqrt{n}))

    #include <bits/stdc++.h>
    using namespace std;
    
    int t, a, b, c, d, k;
    int pr[50005], mb[50005], sum[50005], tot;
    bool np[50005];
    
    void init() {
    	mb[1] = 1;
    	for (int i = 2; i <= 50000; i++) {
    		if (!np[i]) pr[++tot] = i, mb[i] = -1;
    		for (int j = 1; j <= tot && i * pr[j] <= 50000; j++) {
    			np[i*pr[j]] = 1;
    			if (i % pr[j] == 0) {
    				mb[i*pr[j]] = 0;
    				break;
    			} else mb[i*pr[j]] = -mb[i];
    		}
    	}
    	for (int i = 1; i <= 50000; i++) sum[i] = sum[i-1] + mb[i];
    }
    
    int solve(int nn, int mm) {
    	int ret = 0, n = nn / k, m = mm / k;
    	for (int l = 1, r = 0; l <= min(n, m); l = r + 1) {
    		r = min(n / (n / l), m / (m / l));
    		ret += (sum[r] - sum[l-1]) * (n / l) * (m / l); 
    	}
    	return ret;
    }
    
    int main() {
    	scanf("%d", &t);
    	init();
    	while (t--) {
    		scanf("%d %d %d %d %d", &a, &b, &c, &d, &k);
    		printf("%d
    ", solve(b, d) + solve(a-1, c-1) - solve(b, c-1) - solve(a-1, d));
    	}
    	return 0;
    }
    
  • 相关阅读:
    20162309《程序设计与设计结构》第一周学习总结
    20162309《程序设计与数据结构》课程总结
    网络编程与安全实验报告
    四则运算挑战出题
    Android实验报告
    四则运算第二周实验报告
    XP实验报告
    20162319 2017-2018-1 《程序设计与数据结构》第3周学习总结
    20162319 2017-2018-1 《程序设计与数据结构》第1周学习总结
    结对编程-马尔克夫链
  • 原文地址:https://www.cnblogs.com/ak-dream/p/AK_DREAM89.html
Copyright © 2020-2023  润新知