zoukankan      html  css  js  c++  java
  • 【LG2257】YY的GCD

    【LG2257】YY的GCD

    题面

    洛谷

    题解

    题目大意:

    给定(n,m)(sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)为质数])

    我们设(f(x)=[x为质数]),需要找到一个(g)使得(f=1*g),那么(g=mu*f)

    [g(x)=sum_{d|x}mu(frac{x}{d})*f(d)=sum_{p|x}mu(frac{x}{p}) ]

    这样的话,我们要求的就是

    [sum_{i=1}^{n}sum_{j=1}^{m}sum_{d|i,d|j}g(d)\ =sum_{d=1}^{min(n,m)}g(d)sum_{i=1}^{n}sum_{j=1}^{m}[d|i][d|j]\ =sum_{d=1}^{min(n,m)}g(d)lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor ]

    可以用数论分块求出

    代码

    #include <iostream> 
    #include <cstdio> 
    #include <cstdlib> 
    #include <cstring> 
    #include <cmath> 
    #include <algorithm> 
    using namespace std; 
    inline int gi() { 
    	register int data = 0, w = 1; 
    	register char ch = 0; 
    	while (!isdigit(ch) && ch != '-') ch = getchar(); 
    	if (ch == '-') w = -1, ch = getchar(); 
    	while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
    	return w * data; 
    }
    typedef long long ll; 
    const int MAX_N = 1e7 + 5; 
    const int MAX = 1e7; 
    bool is_prime[MAX_N]; 
    int prime[MAX_N], num, mu[MAX_N], s[MAX_N], f[MAX_N]; 
    void sieve() {
    	for (int i = 1; i <= MAX; i++) is_prime[i] = 1; 
    	is_prime[1] = 0, mu[1] = 1;
    	for (int i = 2; i <= MAX; i++) { 
    		if (is_prime[i]) prime[++num] = i, mu[i] = -1; 
    		for (int j = 1; j <= num && i * prime[j] <= MAX; j++) {
    			is_prime[i * prime[j]] = 0; 
    			if (i % prime[j] == 0) break; 
    			mu[i * prime[j]] = -mu[i]; 
    		} 
    	} 
    	for (int i = 1; i <= num; i++)
    		for (int j = 1; prime[i] * j <= MAX; j++) 
    			f[j * prime[i]] += mu[j];
    	for (int i = 1; i <= MAX; i++) s[i] = s[i - 1] + f[i]; 
    }
    ll solve(int a, int b) {
    	ll ans = 0;
    	if (a > b) swap(a, b);
    	for (int l = 1, r = 0; l <= a; l = r + 1) {
    		r = min(a / (a / l), b / (b / l));
    		ans += 1ll * (s[r] - s[l - 1]) * (a / l) * (b / l); 
    	}
    	return ans; 
    } 
    int main () { 
    #ifndef ONLINE_JUDGE 
    	freopen("cpp.in", "r", stdin); 
    #endif
    	sieve();
    	int T = gi(), N, M; 
    	while (T--) {
    		N = gi(), M = gi();
    		printf("%lld
    ", solve(N, M)); 
    	} 
    	return 0; 
    } 
    
  • 相关阅读:
    selenium ide 录制回放link链接报错
    如何打造个人技术影响力
    如何打造个人技术影响力
    三个Bootstrap免费字体和图标库
    程序媛,坚持这几个好习惯让你越来越美
    程序媛,坚持这几个好习惯让你越来越美
    程序媛,坚持这几个好习惯让你越来越美
    程序媛,坚持这几个好习惯让你越来越美
    [慕课笔记]mongodb入门篇
    [慕课笔记]mongodb入门篇
  • 原文地址:https://www.cnblogs.com/heyujun/p/10177766.html
Copyright © 2011-2022 走看看