zoukankan      html  css  js  c++  java
  • 洛谷

    https://www.luogu.org/problemnew/show/P3768

    (F(n)=sumlimits_{i=1}^{n}sumlimits_{j=1}^{n}ijgcd(i,j))

    首先加入方括号并枚举g,提gcd的g:
    (sumlimits_{g=1}^{n}gsumlimits_{i=1}^{n}sumlimits_{j=1}^{n}ij[gcd(i,j)==g])

    后面的方括号里的g也可以提出来,注意前面有两个id,所以:
    (sumlimits_{g=1}^{n}g^3 sumlimits_{i=1}^{lfloorfrac{n}{g} floor}sumlimits_{j=1}^{lfloorfrac{n}{g} floor}ij[gcd(i,j)==1])

    (G(n)=sumlimits_{i=1}^{n}sumlimits_{j=1}^{n}ij[gcd(i,j)==1]) ,则 (F(n)=sumlimits_{g=1}^{n}g^3 G(lfloorfrac{n}{g} floor))(F(n))可以一次对(G(lfloorfrac{n}{g} floor))分块求出来。

    关注 (G(n)) 怎么求。

    先把 (G(n)) 分成两半,设 (H_1(n)=sumlimits_{i=1}^{n}sumlimits_{j=1}^{i}ij[gcd(i,j)==1]) ,显然 (G(n)=2*H_1(n)-1)

    又设(H_2(n)=sumlimits_{i=1}^{n}in[gcd(i,n)==1]) ,则 $H_1(n)=sumlimits_{i=1}^{n}H_2(i) $

    (H_2(n)=nsumlimits_{i=1}^{n}i[gcd(i,n)==1]),这个不是在疯狂lcm里面见过吗?和一个数gcd为1的不比他大的数的和。

    直接套上去:

    (H_2(n)=nH(n)=frac{n^2}{2}([n==1]+varphi(n)))

    所以:
    (H_1(n)=sumlimits_{i=1}^{n}H_2(i) = sumlimits_{i=1}^{n} frac{i^2}{2}([i==1]+varphi(i)))

    故:
    (G(n)=sumlimits_{i=1}^{n} i^2 ([i==1]+varphi(i)) -1= sumlimits_{i=1}^{n} i^2 varphi(i))

    感觉可以用杜教筛来求,先线性筛出1e7以内的 (G(n))


    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    ll n;
    int mod;
    int inv2;
    const int MAXN=1e7;
    
    int pri[MAXN+1];
    int &pritop=pri[0];
    int B[2*MAXN+1];
    int pk[MAXN+1];
    
    void sieve(int n=MAXN) {
        memset(B,-1,sizeof(B));
        B[0]=0;
        pk[1]=1;
        B[1]=1;
        for(int i=2; i<=n; i++) {
            if(!pri[i]) {
                pri[++pritop]=i;
                pk[i]=i;
                ll tmp=1ll*i*i;
                if(tmp>=mod)
                    tmp%=mod;
                tmp*=(i-1);
                if(tmp>=mod)
                    tmp%=mod;
                B[i]=tmp;
            }
            for(int j=1; j<=pritop; j++) {
                int &p=pri[j];
                int t=i*p;
                if(t>n)
                    break;
                pri[t]=1;
                if(i%p) {
                    pk[t]=p;
                    ll tmp=1ll*B[i]*B[p];
                    if(tmp>=mod)
                        tmp%=mod;
                    B[t]=tmp;
                } else {
                    pk[t]=pk[i]*p;
                    if(pk[t]==t) {
                        ll tmp=1ll*t*t;
                        if(tmp>=mod)
                            tmp%=mod;
                        tmp*=(t-i);
                        if(tmp>=mod)
                            tmp%=mod;
                        B[t]=tmp;
                    } else {
                        ll tmp=1ll*B[t/pk[t]]*B[pk[t]];
                        if(tmp>=mod)
                            tmp%=mod;
                        B[t]=tmp;
                    }
                    break;
                }
            }
        }
        for(int i=1; i<=n; i++) {
            ll tmp=(ll)B[i]+B[i-1];
            if(tmp>=mod)
                tmp-=mod;
            B[i]=tmp;
        }
    }
    
    inline ll qpow(ll x,ll n) {
        if(x>=mod)
            x%=mod;
        ll res=1;
        while(n) {
            if(n&1) {
                res*=x;
                if(res>=mod)
                    res%=mod;
            }
            x*=x;
            if(x>=mod)
                x%=mod;
            n>>=1;
        }
        return res;
    }
    
    int inv4;
    int inv6;
    
    inline int s2(ll n) {
        if(n>=mod)
            n%=mod;
        ll tmp=n*(n+1);
        if(tmp>=mod)
            tmp%=mod;
        tmp*=(n*2+1);
        if(tmp>=mod)
            tmp%=mod;
        tmp*=inv6;
        if(tmp>=mod)
            tmp%=mod;
        return tmp;
    }
    
    inline int s3(ll n) {
        if(n>=mod)
            n%=mod;
        ll tmp=n*(n+1);
        if(tmp>=mod)
            tmp%=mod;
        tmp*=tmp;
        if(tmp>=mod)
            tmp%=mod;
        tmp*=inv4;
        if(tmp>=mod)
            tmp%=mod;
        return tmp;
    }
    
    inline int id(ll x){
        if(x<=MAXN)
            return x;
        else
            return n/x+MAXN;
    }
    
    inline int S(ll n) {
        int idn=id(n);
        if(B[idn]!=-1)
            return B[idn];
        ll ret=s3(n);
        for(ll l=2,r; l<=n; l=r+1) {
            ll t=n/l;
            r=n/t;
            ll tmp=s2(r)-s2(l-1);
            if(tmp<0)
                tmp+=mod;
            tmp*=S(t);
            if(tmp>=mod)
                tmp%=mod;
            ret-=tmp;
        }
        ret%=mod;
        if(ret<0)
            ret+=mod;
        return B[idn]=ret;
    }
    
    inline int F(ll n){
        ll res=0;
        for(ll l=1,r;l<=n;l=r+1){
            ll t=n/l;
            r=n/t;
            ll tmp=s3(r)-s3(l-1);
            if(tmp<0)
                tmp+=mod;
            tmp*=S(t);
            if(tmp>=mod)
                tmp%=mod;
            res+=tmp;
        }
        if(res>=mod)
            res%=mod;
        return res;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
    #endif // Yinku
        scanf("%d%lld",&mod,&n);
        inv2=qpow(2,mod-2);
        inv4=qpow(4,mod-2);
        inv6=qpow(6,mod-2);
        sieve(min(n,(ll)MAXN));
        printf("%d
    ",F(n));
        return 0;
    }
    
  • 相关阅读:
    redis 资料
    php 安装redis php扩展
    Unity生命周期
    疫情下的大学生人格发展研究
    对联一句——百花深处
    Unity实现byte[]合成图像
    Unity实现精灵资源动态加载
    数据结构与算法初步
    Unity中激活子物体
    C#实现自定义列表
  • 原文地址:https://www.cnblogs.com/Yinku/p/10998781.html
Copyright © 2011-2022 走看看