HDU 5608 function(杜教篩)

function
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1700 Accepted Submission(s): 607

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

N23N+2=dNf(d)N^2−3N+2=∑_{d|N}f(d)

calulate i=1Nf(i)∑^N_{i=1}f(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.

Sample Input
1
3

Sample Output
2

1231+2=f(1)=01^2-3*1+2=f(1)=0
2232+2=f(2)+f(1)=0>f(2)=02^2-3*2+2=f(2)+f(1)=0->f(2)=0
3233+2=f(3)+f(1)=2>f(3)=23^2-3*3+2=f(3)+f(1)=2->f(3)=2
f(1)+f(2)+f(3)=2f(1)+f(2)+f(3)=2

題意

有這麼一個函數f(x)f(x)滿足
N23N+2=dNf(d)N^2-3N+2=\sum_{d|N}f(d)
然後求
i=1nf(i) mod 109+7\sum_{i=1}^nf(i)\ mod\ 10^9+7

思路

g(n)=n23n+2g(n)=n^2-3n+2
那麼有g(n)=(If)(n)g(n)=(I*f)(n)
左邊是恆等函數IIff的狄利克雷卷積,那麼根據Iμ=eI*\mu=e,兩邊再乘上一個μ\mu,有
(μg)=(μI)f(\mu*g)=(\mu*I)*f
(μg)=f(\mu*g)=f
所以有
f(n)=dnμ(d)g(nd)f(n)=\sum_{d|n}\mu(d)g(\frac{n}{d})
那麼
i=1nf(n)=i=1ndiμ(d)g(id)\sum_{i=1}^nf(n)=\sum_{i=1}^n\sum_{d|i}\mu(d)g(\frac{i}{d})
當前的含義是枚舉1n1-n中每一個i的因子,這個和枚舉1n1-n中每一個數的倍數是等價的,那麼就有
i=1nf(n)=d=1nμ(d)dig(id)\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)\sum_{d|i}g(\frac{i}{d})
i=1nf(n)=d=1nμ(d)i=1ndg(i)\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor}g(i)
S(n)=i=1ng(i)S(n)=\sum_{i=1}^ng(i)則有
S(n)=i=1ni23i=1ni+i=1n2S(n)=\sum_{i=1}^ni^2-3\sum_{i=1}^ni+\sum_{i=1}^n2
S(n)=n(n+1)(2n+1)63n(n+1)2+2nS(n)=\frac{n(n+1)(2n+1)}{6}-3\frac{n(n+1)}{2}+2n
那麼原式就有
i=1nf(n)=d=1nμ(d)S(nd)\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)S(\left \lfloor \frac{n}{d} \right \rfloor)

i=1nf(n)=d=1nμ(d)(nd(nd+1)(2nd+1)63nd(nd+1)2+2nd)\sum_{i=1}^nf(n)=\sum_{d=1}^n\mu(d)(\frac{\left \lfloor \frac{n}{d} \right \rfloor(\left \lfloor \frac{n}{d} \right \rfloor+1)(2\left \lfloor \frac{n}{d} \right \rfloor+1)}{6}-3\frac{\left \lfloor \frac{n}{d} \right \rfloor(\left \lfloor \frac{n}{d} \right \rfloor+1)}{2}+2\left \lfloor \frac{n}{d} \right \rfloor)
莫比烏斯函數的前綴和就可以用杜教篩求了,和函數就可以用分塊來做,提前處理一下6的逆元和2的逆元就可以了

#include<bits/stdc++.h>
using namespace std;
const int N=5e6+5;
const int mod=1e9+7;
const int inv6=166666668;
const int inv2=500000004;
bool vis[N];
int mu[N];
int prime[N];
int cnt;
void init()
{
    cnt=0;
    mu[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            mu[i]=-1;
        }
        for(int j=0;j<cnt&&i*prime[j]<=N;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
            else
                mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=2;i<N;i++)
        mu[i]=mu[i-1]+mu[i];
}
unordered_map<int,int>S;
int Sum(int n)
{
    if(n<N) return mu[n];
    else if(S.find(n)!=S.end())return S[n];
    int ans=1;
    for(int i=2,last;i<=n;i=last+1)
    {
        last=n/(n/i);
        ans=ans-(last-i+1)*Sum(n/i);
    }
    S[n]=ans;
    return ans;
}

int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        long long ans=0;
        for(int i=1,last;i<=n;i=last+1)
        {
            last=n/(n/i);
            long long m=n/i;
            ans=(ans+(Sum(last)-Sum(i-1)+mod)%mod*(m*(m+1)%mod*(2*m%mod+1)%mod*inv6%mod-3*m%mod*(m+1)%mod*inv2%mod+2*m%mod+mod)%mod)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章