zoukankan      html  css  js  c++  java
  • ...

    51nod1239

    给你一个n(n <= 1e10),求euler[1] + euler[2] + euler[3] + ... + euler[n]

    用线性筛预处理一部分,然后递归,递归的时候用map存计算的结果会快很多

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #include <ctime>
    #include <map>
    using namespace std;
    #define rep(i, j, k) for(int i = int(j); i <= int(k); ++ i)
    typedef long long LL;
    map<LL, LL> mp;
    const LL MOD = 1e9 + 7;
    const int N = 1e7 + 5;
    bool isPrime[N];
    int prime[N / 10], euler[N], primeNum = 0;
    int f[N];
    
    inline void sieve() {
        memset(isPrime, 1, sizeof(isPrime));
        euler[1] = 1;
        for (int i = 2; i < N; ++ i) {
            if (isPrime[i]) {
                prime[++ primeNum] = i;
                euler[i] = (i - 1);
            }
            for (int j = 1; j <= primeNum && i * prime[j] < N; ++ j) {
                isPrime[i * prime[j]] = 0;
                if (i % prime[j] == 0) {
                    euler[i * prime[j]] = euler[i] * prime[j];
                    break;
                }
                else euler[i * prime[j]] = euler[i] * (prime[j] - 1);
            }
        }
        f[1] = 1;
        for (int i = 2; i < N; ++ i) f[i] = f[i - 1] + euler[i], f[i] %= MOD;
    }
    LL dfs(LL n) {
        if (n < N) return (LL)f[n];
        if (mp.count(n)) return mp[n];
        LL ret;
        if (n & 1) ret = n % MOD * ((n + 1) / 2 % MOD) % MOD;
        else ret = n / 2 % MOD * ((n + 1) % MOD) % MOD;
        int m = (int)sqrt(n + 0.5);
        for (int i = 2; i <= m; ++ i) {
            ret -= dfs(n / i);
            ret = (ret % MOD + MOD) % MOD;
        }
        for (int t = 1; t < n / m; ++ t) {
            ret -= dfs(t) * (n / t - n / (t + 1));
            ret = (ret % MOD + MOD) % MOD;
        }
        return mp[n] = ret;
    }
    int main() {
        sieve();
        // cout << 1.0 * clock() / CLOCKS_PER_SEC << endl;
        LL n;
        cin >> n;
        cout << dfs(n) << endl;
    }

     1244

    求一段区间内的莫比乌斯函数和。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <map>
    using namespace std;
    typedef long long LL;
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i)
    const int N = 1e7 + 5;
    bool isPrime[N];
    int prime[N / 10], mu[N], primeNum = 0;
    int f[N];
    inline void sieve() {
        memset(isPrime, 1, sizeof(isPrime));
        mu[1] = 1;
        rep(i, 2, N - 1) {
            if (isPrime[i]) {
                mu[i] = -1;
                prime[++ primeNum] = i;
            }
            rep(j, 1, primeNum) {
                if (i * prime[j] >= N) break;
                isPrime[i * prime[j]] = 0;
                if (i % prime[j] == 0) {
                    mu[i * prime[j]] = 0;
                    break;
                }
                else mu[i * prime[j]] = -mu[i];
            }
        }
        rep(i, 1, N - 1) f[i] = f[i - 1] + mu[i];
    }
    map<LL, int> mp;
    LL dfs(LL n) {
        if (n < N) return f[n];
        if (mp.count(n)) return mp[n];
        int ret = 1;
        int m = (int)sqrt(n + 0.5);
        rep(i, 2, m) {
            ret -= dfs(n / i);
        }
        rep(t, 1, n / m - 1) {
            ret -= dfs(t) * (n / t - n / (t + 1));
        }
        return mp[n] = ret;
    }
    int main() {
        sieve();
        LL a, b;
        cin >> a >> b;
        cout << dfs(b) - dfs(a - 1) << endl;
    }

     51nod1237 

    for (int i =1; i <= n; ++i) for (int j = 1; j <= n; ++ j) ret = (ret + gcd(i, j)) %MOD,求ret

    #include <iostream>
    #include <cstring>
    #include <map>
    #include <cmath>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i)
    const int N = 1e7 + 5;
    const LL MOD = 1e9 + 7;
    bool isPrime[N];
    int prime[N / 10], primeNum = 0, euler[N];
    int f[N];
    map<LL, LL> mp;
    inline void sieve() {
        memset(isPrime, 1, sizeof(isPrime));
        euler[1] = 1;
        rep(i, 2, N - 1) {
            if (isPrime[i]) {
                prime[++ primeNum] = i;
                euler[i] = i - 1;
            }
            rep(j, 1, primeNum) {
                if (i * prime[j] >= N) break;
                isPrime[i * prime[j]] = 0;
                if (i % prime[j] == 0) {
                    euler[i * prime[j]] = euler[i] * prime[j];
                    break;
                }
                else euler[i * prime[j]] = euler[i] * (prime[j] - 1);
            }
        }
        rep(i, 1, N - 1) f[i] = f[i - 1] + euler[i], f[i] %= MOD;
    }
    inline LL sqr(LL x) {
        x %= MOD;
        return x * x % MOD;
    }
    LL dfs(LL n) {
        if (n < N) return (LL)f[n];
        if (mp.count(n)) return mp[n];
        LL ret;
        if (n & 1) ret = n % MOD * ((n + 1) / 2 % MOD) % MOD;
        else ret = n / 2 % MOD * ((n + 1) % MOD) % MOD;
        int m = (int)sqrt(n + 0.5);
        for (int i = 2; i <= m; ++ i) {
            ret -= dfs(n / i);
            ret = (ret % MOD + MOD) % MOD;
        }
        for (int t = 1; t < n / m; ++ t) {
            ret -= dfs(t) * (n / t - n / (t + 1));
            ret = (ret % MOD + MOD) % MOD;
        }
        return mp[n] = ret;
    }
    int main() {
        sieve();
        LL n, ret = 0;
        cin >> n;
        int m = (int)sqrt(n + 0.5);
    
        rep(i, 1, m) {
            ret += euler[i] * sqr(n / i) % MOD;
            ret %= MOD;
        }
        rep(t, 1, n / m - 1) {
            LL tmp = dfs(n / t) - dfs(n / (t + 1));
            tmp = (tmp % MOD + MOD) % MOD;
            ret += sqr(t) * tmp % MOD;
            ret %= MOD;
        }
        cout << ret << endl;
    }    

     51nod1238

     for (int i = 1; i <= n; ++ i) for (int j = 1; j <= n; ++j) ans += LCM(i, j);

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i)
    const LL MOD = 1e9 + 7;
    const int N = 1e7 + 5;
    bool isPrime[N];
    int prime[N / 10], primeNum = 0, euler[N];
    LL f[N];
    LL inv2, inv3;
    inline LL qpow(LL a, LL b) {
        a %= MOD;
        LL c = 1;
        while (b) {
            if (b & 1) c = c * a % MOD;
            a = a * a % MOD;  b >>= 1;
        }
        return c; 
    }
    inline LL sqr(LL x) {
        x %= MOD;
        return x * x % MOD;
    }
    inline LL soo(LL x) {
        x %= MOD;
        return x * (x + 1) % MOD * inv2 % MOD;
    }
    inline LL sob(LL x) {
        x %= MOD;
        return sqr(x * (x + 1) % MOD * inv2 % MOD);
    }
    inline LL sos(LL x) {
        x %= MOD;
        return x * (x + 1) % MOD * (2 * x + 1) % MOD * inv2 % MOD * inv3 % MOD;
    }
    inline void sieve() {
        memset(isPrime, 1, sizeof(isPrime));
        euler[1] = 1;
        rep(i, 2, N - 1) {
            if (isPrime[i]) {
                prime[++ primeNum] = i;
                euler[i] = i - 1;
            }
            rep(j, 1, primeNum) {
                if (i * prime[j] >= N) break;
                isPrime[i * prime[j]] = 0;
                if (i % prime[j] == 0) {
                    euler[i * prime[j]] = euler[i] * prime[j];
                    break;
                }
                else euler[i * prime[j]] = euler[i] * (prime[j] - 1);
            }
        }
        rep(i, 1, N - 1) f[i] = f[i - 1] + sqr(i) * euler[i] % MOD, f[i] %= MOD;
    }
    map<LL, LL> mp;
    LL dfs(LL x) {
        if (x < N) return f[x];
        if (mp.count(x)) return mp[x];
        LL ret = sob(x);
        int m = (int)sqrt(x + 0.5);
        rep(i, 2, m) {
            ret -= sqr(i) * dfs(x / i);
            ret = (ret % MOD + MOD) % MOD;
        }
        rep(t, 1, x / m - 1) {
            LL tmp = sos(x / t) - sos(x / (t + 1));
            tmp = (tmp % MOD + MOD) % MOD;
            ret -= tmp * dfs(t);
            ret = (ret % MOD + MOD) % MOD;
        }
        return mp[x] = ret;
    }
    int main() {
        inv2 = qpow(2, MOD - 2);
        inv3 = qpow(3, MOD - 2);
        sieve();
        LL n;
        cin >> n;
        LL ans = 0;
        int m = sqrt(n + 0.5);
        rep(i, 1, m) {
            ans += i * dfs(n / i) % MOD;
            ans %= MOD;
        }
        rep(t, 1, n / m - 1) {
            LL tmp = soo(n / t) - soo(n / (t + 1));
            tmp = (tmp % MOD + MOD) % MOD;
            ans += tmp * dfs(t) % MOD;
            ans %= MOD;
        }
        cout << ans << endl;
    }
  • 相关阅读:
    【Windows】netsh动态配置端口转发
    Python 脚本注册为Windows Service
    【Windows】Python脚本随机启动
    【MySQL】CSV 文件导入MySQL
    【Python】改变对象的字符串显示
    【Python】偏函数
    【Python】装饰器理解
    【Python】什么是闭包
    【Python】高阶函数介绍
    【Python】__all__ 暴露接口
  • 原文地址:https://www.cnblogs.com/tempestT/p/7675857.html
Copyright © 2011-2022 走看看