P3768 简单的数学题

洛谷题目链接

毒瘤题

弄模数弄了我一天,结果少模了一个地方

做法

我们要求:$$(\sum\limits_{i=1}^n \sum\limits_{j=1}^n i\times j\times gcd(i,j))mod\ p$$

我们先不管后面的模\(p\),考虑前面枚举\(gcd(i,j)\):$$\sum\limits_{d=1}^n d \sum\limits_{i=1}^n \sum\limits_{j=1}^n i\times j\ [gcd(i,j)=d]$$

套路的除\(d\):$$\sum\limits_{d=1}^n d^3 \sum\limits_{i=1}^{\left\lfloor \frac{n}{d} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{d} \right\rfloor} i\times j\ [gcd(i,j)=1]$$

后面显然用莫比乌斯反演,我们用性质来变换:$$\sum\limits_{d=1}^n d^3 \sum\limits_{i=1}^{\left\lfloor \frac{n}{d} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{d} \right\rfloor} i\times j \sum\limits_{k|gcd(i,j)} \mu (k)$$

套路的枚举\(k\)

\[\sum\limits_{d=1}^n d \sum\limits_{k=1}^{\left\lfloor \frac{n}{d} \right\rfloor} \mu (k) \sum\limits_{i=1}^{\left\lfloor \frac{n}{d} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{d} \right\rfloor} i\times j\ [k|gcd(i,j)] \]

\(k\)把后面去掉: $$\sum\limits_{d=1}^n d^3 \sum\limits_{k=1}^{\left\lfloor \frac{n}{d} \right\rfloor} \mu (k) k2\sum\limits_{i=1} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{dk} \right\rfloor} i\times j $$

我们用\(T=dk\)带入:$$\sum\limits_{T=1}^n \sum\limits_{d|T} d^3 \mu (\frac{T}{d}) {(\frac{T}{d})}2\sum\limits_{i=1} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{T} \right\rfloor} i\times j$$

前面的\(d^3\)可以和\({(\frac{T}{d})}^2\)消去分母:$$\sum\limits_{T=1}^n \sum\limits_{d|T} d \mu (\frac{T}{d}) T2\sum\limits_{i=1} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{T} \right\rfloor} i\times j$$

换个位置:$$\sum\limits_{T=1}^n T^2 \sum\limits_{d|T} d \mu (\frac{T}{d}) \sum\limits_{i=1}^{\left\lfloor \frac{n}{T} \right\rfloor} \sum\limits_{j=1}^{\left\lfloor \frac{n}{T} \right\rfloor} i\times j$$

我们设函数\(S\):$$S(n)=(\sum\limits_{i=1}^n i)^2$$

那么原式可化为:$$\sum\limits_{T=1}^n T^2 \sum\limits_{d|T} d \mu (\frac{T}{d}) S(\left\lfloor \frac{n}{T} \right\rfloor)$$

因为\(φ=id\times \mu\),所以:$$\sum\limits_{T=1}^n T^2 φ(T)\ S(\left\lfloor \frac{n}{T} \right\rfloor)$$

那么后面我们可以用整除分块来搞,可是前面呢?

杜教筛大法吼啊~~~

我们要求:$$L(n)=\sum\limits_{i=1}^n i^2φ(i)$$

那么就要考虑怎么配\(g,h\)函数:\(h(n)=\sum\limits_{d|n} d^2 φ(d)\ g(\frac{n}{d})\)$

我们发现前面的\(d^2\)很讨厌,自然要想着消去,于是我们设\(g(i)=i^2\):$$h(n)=\sum\limits_{d|n} d^2 φ(d)\ (\frac{n}{d})^2$$

\[h(n)=\sum\limits_{d|n} n^2φ(d) \]

\[h(n)=n^2\sum\limits_{d|n} φ(d) \]

\[h(n)=n^3 \]

那么我们发现这样配对的话可以很容易求出\(g,h\),(别说你没学过小学奥数)

把杜教筛的套路式弄出来:$$g(1)L(n)=\sum\limits_{i=1}^n h(i) -\sum\limits_{d=2}^n g(d)L(\frac{n}{d})$$

带入\(g,h\)函数:$$L(n)=\sum\limits_{i=1}^n i^3 -\sum\limits_{d=2}^n d^2L(\frac{n}{d})$$

而我们知道:$$\sum\limits_{i=1}^n i^2 =\frac{n(1+n)(2n+1)}{6}$$

\[\sum\limits_{i=1}^n i^3=(\sum\limits_{i=1}^n i)^2=\frac{n^2(1+n)^2}{4} \]

所以很容易用杜教筛求出来啦

要注意要模\(p\),所以要算出\(4,6\)的逆元

接下来是美滋滋的代码时间~~~

#include<iostream>
#include<cstdio>
#include<cmath>
#include<tr1/unordered_map>
#define int long long
#define N 8000007
using namespace std;
int n,mod,cnt,inv4,inv6;
int phi[N],prime[N];
bool isp[N];
tr1::unordered_map<int,int> map_;
void Get_phi(int x)
{
    phi[1]=1;
    for(int i=2;i<=x;++i)
    {
        if(!isp[i])
        {
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&(i*prime[j])<=x;++j)
        {
            isp[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                phi[i*prime[j]]=(phi[i]*prime[j])%mod;
                break;
            }
            else
                phi[i*prime[j]]=(phi[i]*phi[prime[j]])%mod;
        }
    }
    for(int i=1;i<=x;++i)
        phi[i]=(phi[i-1]+phi[i]*i%mod*i%mod)%mod;
}
int qpow(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int L(int x)
{
    x%=mod;
    int num=x%mod*(x+1)%mod;
    num=num*num%mod*inv4%mod;
    return num;
}
int L1(int x)
{
    x%=mod;
    int num=x*(x+1)%mod*(x+x+1)%mod*inv6%mod;
    return num;
}
int Ans(int x)
{
    if(x<=N-7)
        return phi[x];
    if(map_[x])
        return map_[x];
    int ans=L(x);
    for(int l=2,r;l<=x;l=r+1)
    {
        r=x/(x/l);
        ans-=(Ans(x/l)*(L1(r)-L1(l-1)+mod)%mod)%mod;
        ans%=mod;
    }
    //printf("%lld\n",ans);
    return map_[x]=(ans+mod)%mod;
}
signed main()
{
    scanf("%lld%lld",&mod,&n);
    inv4=qpow(4,mod-2),inv6=qpow(6,mod-2);
    Get_phi(N-7);
    int ans=0;
    for(int l=1,r;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans+=(((Ans(r)-Ans(l-1)+mod)%mod)*(L(n/l)%mod))%mod;
        ans%=mod;
        //printf("%lld\n",ans);
    }
    printf("%lld",(ans+mod)%mod);
    return 0;
}
/*
1000000007 9786510294 

*/
posted @ 2019-07-04 08:56  模拟退火  阅读(167)  评论(0编辑  收藏  举报