• 洛谷 P3327 [SDOI2015]约数个数和


    题意:

    $d(n)$为$n$的约数个数, 求$sum_{i = 1} ^ {n}sum_{j = 1}^{m}d(i * j)$

    思路:
    $d(i * j) = sum_{x|i}sum_{y|j}[gcd(x, y) = 1]$

               $= sum_{x | i}sum_{y | j}sum_{k | gcd(x, y)}mu(k)$

               $= sum_{k}mu(k)sum_{x | i}sum_{y | j}[k | x][k | y]$

               $= sum_{k}mu(k)sum_{x | frac{i}{k}}sum_{y|frac{j}{k}}$

               $= sum_{k}mu(k)d(frac{i}{k})d(frac{j}{k})$

    则$sum_{i = 1} ^ {n}sum_{j = 1}^{m}d(i * j)$ 

     $=sum_{k}mu(k)sum_{i = 1} ^ {n}d(frac{i}{k})sum_{j = 1}^{m} d(frac{j}{k})$

     $=sum_{k}mu(k)sum_{i = 1} ^ {lfloorfrac{n}{k} floor} d(i)sum_{j = 1}^{lfloorfrac{m}{k} floor} d(j)$

    线性筛求$mu(i)$和$d(i)$的前缀和,分块求解

    Code:

    #pragma GCC optimize(3)
    #pragma GCC optimize(2)
    #include <map>
    #include <set>
    // #include <array>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <stdlib.h>
    #include <algorithm>
    // #include <unordered_map>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int, int> PII;
    
    #define Time (double)clock() / CLOCKS_PER_SEC
    
    #define sd(a) scanf("%d", &a)
    #define sdd(a, b) scanf("%d%d", &a, &b)
    #define slld(a) scanf("%lld", &a)
    #define slldd(a, b) scanf("%lld%lld", &a, &b)
    
    const int N = 1e7 + 20;
    const int M = 1e5 + 20;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    
    ll cnt = 0, primes[N], phi[N], mu[N], d[N], c[N], sum[N] = {0}, sd[N] = {0};
    map<ll, ll> su;
    bool st[N];
    
    int n, m, p, k;
    
    void get(ll n){
        // phi[1] = 1;
        mu[1] = 1;
        d[1] = 1;
        for(ll i = 2; i <= n; i ++){
            if(!st[i]){
                primes[cnt ++] = i;
                // phi[i] = i - 1;
                mu[i] = -1;
                d[i] = 2;
                c[i] = 1;
            }
            for(int j = 0; primes[j] <= n / i; j ++){
                st[i * primes[j]] = true;
                if(i % primes[j] == 0){
                    // phi[i * primes[j]] = primes[j] * phi[i];
                    mu[i * primes[j]] = 0;
                    d[i * primes[j]] = d[i] / (c[i] + 1) * (c[i] + 2);
                    c[i * primes[j]] = c[i] + 1;
                    break;
                }
                // phi[i * primes[j]] = (primes[j] - 1) * phi[i];
                mu[i * primes[j]] = - mu[i];
                d[i * primes[j]] = d[i] * 2;
                c[i * primes[j]] = 1;
            }
        }
    
        for(int i = 1; i <= n; i ++){
            sum[i] = sum[i - 1] + mu[i];
        }
    
        for(int i = 1; i <= n; i ++){
            sd[i] = sd[i - 1] + d[i];
        }
    }
    
    
    ll cal(int a, int b){
        ll res = 0;
        if(a > b) swap(a, b);
        for(int l = 1, r; l <= a; l = r + 1){
            r = min(a / (a / l), b / (b / l));
            res += (sum[r] - sum[l - 1]) * sd[a / l] * sd[b / l];
        }
        return res;
    }
    
    
    void solve()
    {
        int n, m;
        sdd(n, m);
        printf("%lld
    ", cal(n, m));
    
    }
    
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("/home/jungu/code/in.txt", "r", stdin);
        // freopen("/home/jungu/code/out.txt", "w", stdout);
        // freopen("/home/jungu/code/practice/out.txt","w",stdout);
    #endif
        // ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
    
        int T = 1;
        sd(T);
        k = 50000;
        get(k);
        // init(10000000);
        // int cas = 1;
        while (T--)
        {
            // printf("Case #%d:", cas++);
            solve();
        }
    
        return 0;
    }
  • 相关阅读:
    MySQL轻量级监测工具—doDBA
    MySQL构建百万级数据
    MySQL备份与恢复—xtrabackup
    MySQL8.0.15二进制包安装
    「考试」省选51
    「总结」二次剩余
    「考试」省选50
    「总结」$pdf$课:$dp2$
    「考试」省选49
    「考试」省选48
  • 原文地址:https://www.cnblogs.com/jungu/p/13553704.html
Copyright © 2020-2023  润新知