...

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;
}

 

posted @ 2017-10-16 10:36  zd11024  阅读(127)  评论(0编辑  收藏  举报