zoukankan      html  css  js  c++  java
  • [BZOJ2820]YY的GCD

    题目大意

    给你 (n, m) 求 $displaystyle sum_{i = 1}^n sum_{j = 1}^m [ gcd(x, y) == p ] $

    解析

    这道题实际上是上一道解决的HAOI2011 ProblemB的弱化版

    同样的我们的我们可以设出 (F(x)) , (f(x)),然后用莫比乌斯反演推出 (f(x))

    然后进行数论分块就行了

    
    #include <bits/stdc++.h>
    using namespace std;
    
    int T;
    
    const int maxn = 1e7 + 10;
    
    int prime[maxn], mu[maxn], n, m, tot;
    long long f[maxn];
    
    inline void sieve() {
    	mu[1] = 1; fill(prime, prime + maxn, 1); tot = 0;
    	for (int i = 2; i < maxn; ++ i) {
    		if (prime[i]) prime[++tot] = i, mu[i] = -1;
    		for (int j = 1; j <= tot && i * prime[j] < maxn; ++ j) {
    			prime[i * prime[j]] = 0;
    			if (i % prime[j] == 0) {
    				mu[i * prime[j]] = 0;
    				break;
    			} else {
    				mu[i * prime[j]] = -mu[i];
    			}
    		}
    	}
    
    	for (int i = 1; i <= tot; ++ i) {
    		for (int j = 1; j * prime[i] < maxn; ++ j) {
    			f[j * prime[i]] += mu[j];
    		}
    	}
    	for (int i = 1; i < maxn; ++ i) f[i] += f[i - 1];
    }
    
    int main() {
    	sieve();
    	scanf("%d", &T);
    	while (T --) {
    		scanf("%d%d", &n, &m);
    		if (n > m) swap(n, m);
    		long long ans = 0;
    		for (int i = 1, nxt; i <= n; i = nxt + 1) {
    			nxt = min(n / (n / i), m / (m / i));
    			ans += (f[nxt] - f[i - 1]) * (n / i) * (m / i);
    		}
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    Redis学习笔记——环境搭建
    SQL 记录
    路径“D:svn.....”的访问被拒绝问题处理
    去除浏览器自动给input赋值的问题
    获取用户IP
    JS对身份证号码进行验证方法
    JS 实现倒计时
    SQL 游标
    .net上传图片实例
    生成唯一码
  • 原文地址:https://www.cnblogs.com/Alessandro/p/9750135.html
Copyright © 2011-2022 走看看