P3768 简单的数学题(莫比乌斯反演+杜教筛)

P3768 简单的数学题

题意:

输入 p ( 5 × 1 0 8 ≤ p ≤ 1.1 × 1 0 9 且 p 为 质 数 ) , n ( 1 0 10 ) p(5\times 10^8\leq p\leq 1.1\times 10^9且p为质数),n(10^{10}) p(5×108p1.1×109p),n(1010)
( ∑ i = 1 n ∑ j = 1 n i j g c d ( i , j ) ) m o d    p (\sum_{i=1}^{n}\sum_{j=1}^{n}ijgcd(i,j))\mod p (i=1nj=1nijgcd(i,j))modp

题解:

  • 反演:
    ∑ i = 1 n ∑ j = 1 n i j g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=1}^nijgcd(i,j) i=1nj=1nijgcd(i,j)
    = ∑ d = 1 n d ∑ i = 1 n ∑ j = 1 n i j [ g c d ( i , j ) = = d ] =\sum_{d=1}^nd\sum_{i=1}^{n}\sum_{j=1}^{n}ij[gcd(i,j)==d] =d=1ndi=1nj=1nij[gcd(i,j)==d]
    = ∑ d = 1 n d 3 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ i j [ g c d ( i , j ) = = 1 ] =\sum_{d=1}^nd^3\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor \frac{n}{d}\rfloor}ij[gcd(i,j)==1] =d=1nd3i=1dnj=1dnij[gcd(i,j)==1]
    = ∑ d = 1 n d 3 ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ i j ∑ k ∣ g c d ( i , j ) μ ( k ) =\sum_{d=1}^{n}d^3\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}ij\sum_{k\mid gcd(i,j)}\mu(k) =d=1nd3i=1dnj=1dnijkgcd(i,j)μ(k)
    = ∑ d = 1 n d 3 ∑ k = 1 ⌊ n d ⌋ k 2 ∑ i = 1 ⌊ n d k ⌋ ∑ j = 1 ⌊ n d k ⌋ i j μ ( k ) =\sum_{d=1}^{n}d^3\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}k^2\sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{dk}\rfloor }ij\mu(k) =d=1nd3k=1dnk2i=1dknj=1dknijμ(k)
    = ∑ d = 1 n d 3 ∑ k = 1 ⌊ n d ⌋ k 2 ( s u m ( ⌊ n d k ⌋ ) ) 2 μ ( k ) =\sum_{d=1}^{n}d^3\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor }k^2(sum(\lfloor\frac{n}{dk}\rfloor))^2\mu(k) =d=1nd3k=1dnk2(sum(dkn))2μ(k)
    T = d k T=dk T=dk;其中 s u m ( i ) = 1 + 2 + ⋯ + i sum(i)=1+2+\dots+i sum(i)=1+2++i
    = ∑ T = 1 n ( s u m ( ⌊ n T ⌋ ) ) 2 ∑ d ∣ T d 3 ( T d ) 2 μ ( T d ) =\sum_{T=1}^{n}(sum(\lfloor\frac{n}{T}\rfloor))^2\sum_{d\mid T}d^3(\frac{T}{d})^2\mu(\frac{T}{d}) =T=1n(sum(Tn))2dTd3(dT)2μ(dT)
    = ∑ T = 1 n ( s u m ( ⌊ n T ⌋ ) ) 2 T 2 ∑ d ∣ T d μ ( T d ) =\sum_{T=1}^{n}(sum(\lfloor\frac{n}{T}\rfloor))^2T^2\sum_{d\mid T}d\mu(\frac{T}{d}) =T=1n(sum(Tn))2T2dTdμ(dT)
    = ∑ T = 1 n ( s u m ( ⌊ n T ⌋ ) ) 2 T 2 ϕ ( T ) =\sum_{T=1}^{n}(sum(\lfloor\frac{n}{T}\rfloor))^2T^2\phi(T) =T=1n(sum(Tn))2T2ϕ(T)
  • 杜教筛:
    s u m ( ⌊ n T ⌋ ) sum(\lfloor\frac{n}{T}\rfloor) sum(Tn)这一部分数论分块就好
    令 f [ i ] = i 2 ϕ ( i ) ; g [ i ] = i 令f[i]=i^2\phi(i);g[i]=i f[i]=i2ϕ(i);g[i]=i
    f ∗ g ( n ) = n 2 f*g(n)=n^2 fg(n)=n2于是套用杜教筛:
    S [ n ] = ∑ i = 1 n f ∗ g ( i ) − ∑ i = 2 n g [ i ] × S [ ⌊ n l ⌋ ] g [ 1 ] S[n]=\frac{\sum_{i=1}^nf*g(i)-\sum_{i=2}^{n}g[i]\times S[\lfloor\frac{n}{l}\rfloor]}{g[1]} S[n]=g[1]i=1nfg(i)i=2ng[i]×S[ln]

注意: 除法尽量乘逆元,不然容易出错。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define i128 __int128
ll p,n;
const int N=1e6+9;
int primes[N],tot;
bool prime[N];
ll f[N],he[N];
int inv2,inv6;
int poww(int a,int b,int c){
    int ans=1,base=a;
    while(b){
        if(b&1)ans=1ll*ans*base%c;
        base=1ll*base*base%c;
        b>>=1;
    }
    return ans;
}
void init(){
    f[1]=he[1]=1;
    for(int i=2;i<N;i++){
        if(!prime[i])primes[++tot]=i,f[i]=1ll*i*i%p*(i-1)%p;
        for(int j=1;j<=tot&&primes[j]*i<N;j++){
            prime[primes[j]*i]=1;
            if(i%primes[j]==0){
                f[i*primes[j]]=f[i]*primes[j]%p*primes[j]%p*primes[j]%p;
                break;
            }else f[i*primes[j]]=f[i]*f[primes[j]]%p;
        }
    }
    for(int i=2;i<N;i++)he[i]=(he[i-1]+f[i])%p;
}
unordered_map<ll,ll>mp;
ll gi(ll n){
    ll n1=n,n2=(n+1),n3=(2*n+1);
    if(n1%2==0)n1/=2;else n2/=2;
    if(n1%3==0)n1/=3;else if(n2%3==0)n2/=3;else n3/=3;
    return i128(n1)*n2%p*n3%p;
}
ll sum(ll x){
    if(x<N)return he[x];
    if(mp.count(x))return mp[x];
    ll t=i128(x)*(x+1)/2%p;t=t*t%p;
    for(ll l=2,r;l<=x;l=r+1){
        r=x/(x/l);
        ll u=(gi(r)+p-gi(l-1))%p;
        t=(t+p-sum(x/l)*u%p)%p;
    }
    return mp[x]=t;
}
signed main(){
  //  freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
    cin>>p>>n;
    init();
    inv2=poww(2,p-2,p),inv6=poww(6,p-2,p);
    ll ans=0;
    for(ll l=1,r;l<=n;l=r+1){
        r=n/(n/l);
        ll t=n/l;
        t=i128(t)*(t+1)/2%p;
      //  t=(i128)t*(t+1)%p*inv2%p;
        ll y=(sum(r)+p-sum(l-1))%p;
        ans=(ans+t*t%p*y%p)%p;
    }
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值