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; 
    } 
    
  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/heyujun/p/10177766.html
Copyright © 2011-2022 走看看