zoukankan      html  css  js  c++  java
  • [国家集训队]Crash的数字表格 / JZPTAB 题解

    知识点:

    Dirichlet 前缀和 + 线性筛。

    推导:

    默认 (n leq m)

    (ans = displaystyle sum_{i = 1}^n sum_{j = 1}^{m} lcm(i,j) \ = displaystyle sum_{d = 1}^{n} d sum_{i = 1}^{lfloor frac{n}{d} floor} sum_{j = 1}^{lfloor frac{m}{d} floor} ij \ = displaystyle sum_{d = 1}^{n} d sum_{i = 1}^{lfloor frac{n}{d} floor} sum_{j = 1}^{lfloor frac{m}{d} floor} ij \ = displaystyle sum_{d = 1}^{n} d sum_{k = 1}^{lfloor frac{n}{d} floor} mu(k)k^2 sum_{i = 1}^{lfloor frac{n}{kd} floor} sum_{j = 1}^{lfloor frac{m}{kd} floor} ij)

    下面不妨令 (T = kd)。可以得到:

    (ans = displaystyle sum_{T = 1}^n T sum_{d|T} mu(d)d sum_{i = 1}^{lfloor frac{n}{T} floor} sum_{j = 1}^{lfloor frac{m}{T} floor} ij)

    不妨令 (g(n, T)) = (displaystyle sum_{i = 1}^{lfloor frac{n}{T} floor}),可以很容易得到 (g(T) = (frac{n}{T} + 1) * frac{n}{T} / 2)

    那么

    (ans = displaystyle sum_{T = 1}^n (T sum_{d|T} mu(d)d) imes g(n, T) imes g(m, T))

    前面的 (displaystyle sum_{d|T} mu(d)d) 用 Dirichlet 前缀和预处理即可在 (O(n log log n)) 的复杂度内完成问题的预处理。

    对于询问用整除分块优化即可做到 (sqrt{n}) 处理。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int Mod = 20101009, MAXN = 1e7 + 5, inv = (Mod + 1) >> 1;
    int n, m;
    int Prime[MAXN / 11], Mu[MAXN], tot = 0, S[MAXN];
    bool bk[MAXN];
    void GetPrime(int N) {
        Mu[1] = 1;
        for(int i = 2 ; i <= N ; i ++) {
            if(!bk[i]) Prime[++ tot] = i, Mu[i] = -1; 
            for(int j = 1 ; j <= tot && Prime[j] * i <= N; j ++) {
                bk[Prime[j] * i] = 1;
                if(i % Prime[j] == 0) break;
                Mu[Prime[j] * i] = - Mu[i];
            }
        }
        for(int i = 1 ; i <= N ; i ++) S[i] = 1ll * ((Mu[i] + Mod) % Mod) * i % Mod;
        return ;
    }
    int Sum(int x) { return 1ll * x * (x + 1) % Mod * inv % Mod; }
    
    int main() {
        cin >> n >> m;
        if(n > m) swap(n, m);
        GetPrime(n);
        for(int i = 1 ; i <= tot ; i ++) 
            for(int j = 1 ; j * Prime[i] <= n ; j ++)
            S[Prime[i] * j] += S[j], S[Prime[i] * j] %= Mod;
        int Ans = 0;
        for(int i = 1 ; i <= n ; i ++) {
            Ans += 1ll * i * S[i] % Mod * Sum(n / i) % Mod * Sum(m / i) % Mod;
            Ans %= Mod;
        }
        cout << Ans;
        return 0;
    }
    
    By MYCui
  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/MYCui/p/15028784.html
Copyright © 2011-2022 走看看