hdoj - 5608 function【杜教筛】+【莫比乌斯反演】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42671946/article/details/100136518

function

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1908    Accepted Submission(s): 678


 

Problem Description

There is a function f(x),which is defined on the natural numbers set N,satisfies the following eqaution

N2−3N+2=∑d|Nf(d)

calulate ∑Ni=1f(i)  mod 109+7.

 

Input

the first line contains a positive integer T,means the number of the test cases.

next T lines there is a number N


T≤500,N≤109

only 5 test cases has N>106.

 

Output

Tlines,each line contains a number,means the answer to the i-th test case.

扫描二维码关注公众号,回复: 7657718 查看本文章

 

Sample Input

 

1 3

 

Sample Output

 

2 $1^2-3*1+2=f(1)=0$ $2^2-3*2+2=f(2)+f(1)=0->f(2)=0$ $3^2-3*3+2=f(3)+f(1)=2->f(3)=2$ $f(1)+f(2)+f(3)=2$

 

Source

BestCoder Round #68 (div.2)

分析:首先根据数据范围可以看出这是一道杜教筛。

同时给出了n^2-3n+2=\sum _{d|n}f(d)

此时对于g(1)S(n)=\sum_{i=1}^n\sum _{d|i}f(d)*g(\frac{i}{d})-\sum _{d=2}^ng(d)*S([\frac{n}{d}])

直接令g=I

则有S(n)=\sum_{i=1}^n i^2-3i+2-\sum _{d=2}^nS([\frac{n}{d}])

杜教筛的部分到这里就做完了,再考虑一下预处理的部分。

F(n)=n^2-3n+2=\sum _{d|n}f(d)

那么反演一下得到f(n)=\sum _{d|n}u(d)*F([\frac{n}{d}])

直接nlogn筛一下就可以了。

#include "bits/stdc++.h"

using namespace std;
const int mod = 1e9 + 7;
bool isprim[1000000];
long long mu[1000004];
long long f[1000004];
vector<long long> prim;

long long F(long long n) {
    return (n * n % mod - 3 * n % mod + 2 + mod) % mod;
}

void init() {
    memset(isprim, true, sizeof(isprim));
    memset(mu, 0, sizeof(mu));
    mu[1] = 1;
    for (int i = 2; i <= 1000000; ++i) {
        if (isprim[i]) {
            mu[i] = -1;
            prim.push_back(i);
        }
        for (int j = 0; j < prim.size() && i * prim[j] <= 1000000; ++j) {
            isprim[i * prim[j]] = 0;
            if (i % prim[j] == 0)break;
            else mu[i * prim[j]] = -mu[i];
        }
    }
    for (int i = 1; i <= 1000000; ++i) {
        for (int j = i; j <= 1000000; j += i) {
            f[j] += mu[i] * F(j / i) % mod;
            f[j] = (f[j] + mod) % mod;
        }
    }
    for (int i = 1; i <= 1000000; ++i) {
        f[i] = (f[i] + f[i - 1]) % mod;
    }
}


unordered_map<int, int> mp;

long long qk(long long a, long long n) {
    long long res = 1;
    while (n) {
        if (n & 1)res = res * a % mod;
        n >>= 1;
        a = a * a % mod;
    }
    return res;
}

long long inv(long long a) {
    return qk(a, mod - 2);
}

long long inv2 = inv(2), inv6 = inv(6);

long long getans(long long n) {
    if (mp.count(n))return mp[n];
    if (n <= 1000000)return f[n];
    long long ans = 0;
    ans = 1LL * n * (n + 1) % mod * (2 * n + 1) % mod * inv6 % mod;
    ans = (ans - 3 * n % mod * (n + 1) % mod * inv2 % mod + mod) % mod;
    ans = ans + 2 * n;
    ans %= mod;
    long long l = 2, r;
    for (; l <= n; l = r + 1) {
        r = n / (n / l);
        long long temp = 1ll * (r - l + 1) * getans(n / l) % mod;
        ans = (ans - temp + mod) % mod;
    }
    return mp[n] = ans;
}

int main() {
    int n;
    init();
    int t;
    cin >> t;
    while (t--) {
        scanf("%d", &n);
        printf("%lld\n", getans(n));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42671946/article/details/100136518
今日推荐