• Luogu 4900 食堂


    一道把很多东西放在一起的练手题。

    $$sum_{i = A}^{B}sum_{j = 1}^{i}left { frac{i}{j} ight } = sum_{i = A}^{B}sum_{j = 1}^{i}frac{n - left [ frac{n}{j} ight] * j}{i} = sum_{i = A}^{B}(i * sum_{j = 1}^{i}inv(j) - sum_{j = 1}^{i}left lfloor frac{n}{j} ight floor)$$

    这样子把里面的$(i * sum_{j = 1}^{i}inv(j) - sum_{j = 1}^{i}left lfloor frac{n}{j} ight floor)$算出来做个前缀和就好了。

    前面的那个东西可以$O(n)$递推然后前缀和算出来,而后面的那个东西其实就是$sum_{i = 1}^{n}d(i)$($d(i)$表示$i$的约数个数)。

    证明:

    $$sum_{i = 1}^{n}d(i) = sum_{i = 1}^{n}sum_{j = 1}^{i}left [ j| i ight] = sum_{j = 1}^{n}sum_{i = 1}^{n}left [ j| i ight] = sum_{i = 1}^{n}left lfloor frac{n}{i} ight floor$$

    这样子线性筛之后前缀和就做完了。

    记得数组开少一点……我就是这样MLE了一次。

    时间复杂度$O(n)$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e6 + 5;
    const int Maxn = 1e6;
    const ll P = 998244353LL;
    
    int testCase, pCnt = 0, pri[N], low[N];
    ll inv[N], d[N], h[N]; 
    bool np[N];
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48; 
        X *= op;
    }
    
    template <typename T>
    inline void inc(T &x, T y) {
        x += y;
        if(x >= P) x -= P;
    }
    
    inline void sieve() {
        d[1] = 1;
        for(int i = 2; i <= Maxn; i++) {
            if(!np[i]) 
                pri[++pCnt] = i, low[i] = i, d[i] = 2;
            for(int j = 1; i * pri[j] <= Maxn && j <= pCnt; j++) {
                np[i * pri[j]] = 1;
                if(i % pri[j] == 0) {
                    low[i * pri[j]] = pri[j] * low[i];
                    if(low[i] == i) d[i * pri[j]] = d[i] + 1;
                    else d[i * pri[j]] = d[i / low[i]] * d[pri[j] * low[i]];
                    break;    
                }
                low[i * pri[j]] = pri[j]; 
                d[i * pri[j]] = d[i] * d[pri[j]]; 
            }
        }
        
        for(int i = 1; i <= Maxn; i++) inc(d[i], d[i - 1]);
    }
    
    int main() {
        sieve();
        inv[1] = 1LL;
        for(int i = 2; i <= Maxn; i++) inv[i] = inv[P % i] * (P - P / i) % P;
        for(int i = 1; i <= Maxn; i++) inc(inv[i], inv[i - 1]);
        
        for(int i = 1; i <= Maxn; i++) h[i] = (1LL * i * inv[i] % P - d[i] + P) % P;
        for(int i = 1; i <= Maxn; i++) inc(h[i], h[i - 1]);
        
        read(testCase);
        for(int l, r; testCase--; ) {
            read(l), read(r);
            printf("%lld
    ", (h[r] - h[l - 1] + P) % P);
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    Cg学习
    Unity URP
    unity官方案例水效果解析
    Unity使用Xlua框架热更
    隐私政策以及用户协议
    iOS App 从点击到启动
    iOS编程中throttle那些事
    Homebrew安装
    ios 开发证书 appids 描述文件关系
    学习网站
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/10110804.html
Copyright © 2020-2023  润新知