zoukankan      html  css  js  c++  java
  • 51nod1847 奇怪的数学题

    Description

    给出 $N,K$ ,请计算下面这个式子:
    $sum _{i=1}^n sum_{j=1}^n sgcd(i,j)^k$
    其中,$sgcd(i, j)$表示$(i, j)$的所有公约数中第二大的,特殊地,如果$gcd(i, j) = 1$, 那么$sgcd(i, j) = 0$。
    考虑到答案太大,请输出答案对$2^{32}$取模的结果.
    $1 leq N leq 10^9,1 leq K leq 50$

    Solution

    设$f(x)$为$x$的次大的因数,那么原式可化为

    egin{align}
    & sum _{i=1}^n sum_{j=1}^n sgcd(i,j)^k\
    = & sum _{i=1}^n sum _{j=1}^n f((i,j))^k\
    = & sum _{d=1}^n f^k(d) sum _{i=1}^{lfloor frac{n}{d} floor }sum _{j=1}^{lfloor frac{n}{d} floor}[(i,j)=1]\
    = & sum _{d=1}^n f^k(d) left ( 2sum _{i=1}^{lfloor frac {n}{d} floor }varphi(i)-1 ight )
    end{align}

    再定义$G_n=sum _{i=1}^n f(i)$,定义Min_25中的$g$函数为符合要求的$x^k$之和

    发现在做$g$转移时:

    $$g_{i,j}=g_{i-1,j}-p_j^k(g_{lfloor frac{i}{p_j} floor ,j-1 }-g_{p_{j-1},j-1})$$

    括号内的内容即为该数本身除以它的最小质因数,就是题中的次大因数,所以在转移$g$的同时记录括号中的数的和,这样可以得到所有整除点的$G$值

    $g$函数初始化的时候要求自然数幂之和,使用第二类斯特林数和普通幂的转化

    欧拉函数可以用杜教筛得到整除点的值

    #include<unordered_map>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int tot,cnt,id1[100005],id2[100005];
    unsigned int phi[1000005],S[60][60],pw[1000005],w[200005],g1[200005],g0[200005],sp[1000005],G[1000005],ans,pre,now;
    long long n,K,prime[1000005],sq;
    bool vst[1000005];
    unordered_map<int,unsigned int>mp;
    inline int read(){
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    unsigned int ksm(unsigned int a,unsigned int p){
        unsigned int ret=1;
        while(p){
            if(p&1)ret*=a;
            a*=a,p>>=1;
        }
        return ret;
    }
    unsigned int calc(long long x){
        unsigned int ret=0,temp;
        for(unsigned int i=1;i<=K;i++){
            int t=(x-i+1)%(i+1);
            temp=1;
            for(long long j=x-i+1;j<=x+1;j++,++t){
                if(t>=i+1)t-=i+1;
                if(!t)temp*=(unsigned int)j/(i+1);
                else temp*=(unsigned int)j;
            }
            ret+=S[K][i]*temp;
        }
        return ret;
    }
    unsigned int djs(long long x){
        if(x<=1000000)return phi[x];
        if(mp.find(x)!=mp.end())return mp[x];
        unsigned int ret=0;
        if(x&1)ret=(x+1)/2*x;
        else ret=x/2*(x+1);
        for(unsigned int i=2;i<=x;){
            unsigned int j=x/(x/i);
            ret-=djs(x/i)*(j-i+1),i=j+1;
        }
        return mp[x]=ret;
    }
    int main(){
        n=read(),K=read(),sq=sqrt(n),phi[1]=1;
        for(int i=2;i<=1000000;i++){
            if(!vst[i])prime[++tot]=i,phi[i]=i-1;
            for(int j=1;j<=tot&&i*prime[j]<=1000000;j++){
                vst[i*prime[j]]=true;
                if(!(i%prime[j])){phi[i*prime[j]]=phi[i]*prime[j];break;}
                else phi[i*prime[j]]=phi[i]*phi[prime[j]];
            }
        }
        for(int i=1;i<=1000000;i++)phi[i]+=phi[i-1];
        for(int i=1;i<=K;i++){
            S[i][1]=1;
            for(unsigned int j=2;j<=i;j++)S[i][j]=S[i-1][j]*j+S[i-1][j-1];
        }
        for(int i=1;i<=tot;i++)pw[i]=ksm(prime[i],K),sp[i]=sp[i-1]+pw[i];
        for(int i=1;i<=n;){
            int j=n/(n/i);
            w[++cnt]=n/i,g1[cnt]=calc(w[cnt])-1,g0[cnt]=w[cnt]-1,n/i<=sq?id1[n/i]=cnt:id2[n/(n/i)]=cnt,i=j+1;
        }
        for(int i=1;i<=tot;i++)for(int j=1;j<=cnt&&1ll*prime[i]*prime[i]<=w[j];j++){
            int id=w[j]/prime[i]<=sq?id1[w[j]/prime[i]]:id2[n/(w[j]/prime[i])];
            g1[j]-=pw[i]*(g1[id]-sp[i-1]),g0[j]-=g0[id]-(i-1),G[j]+=g1[id]-sp[i-1];
    //        cout<<g0[j]<<" ";
        }
        for(int i=2;i<=n;){
            int j=n/(n/i),id=j<=sq?id1[j]:id2[n/j];
            now=G[id]+g0[id],ans+=(djs(n/i)*2-1)*(now-pre),pre=now,i=j+1;
        }
        printf("%u",ans);
        return 0;
    }//3656808373
    奇怪的数学题
  • 相关阅读:
    代码1
    js中级第13天
    dom 浏览器模型
    js中级第12天
    js中级第11天
    js中级第十天
    js中级第九天
    js中级第8天
    js中级第六天
    js中级第七天
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14459855.html
Copyright © 2011-2022 走看看