zoukankan      html  css  js  c++  java
  • [湖北省队互测2014] 一个人的数论

    题意:

    定义$f_{d}(n)$为所有小于n且与n互质的正整数的d次方之和。

    给定$d,n=prod limits_{i=1}^{w}{p_{i}^{a_{i}}}$,求$f_{d}(n)$对$10^{9}+7$取模的值。

    $dleq 100,wleq 1000,p_{i},a_{i}leq 10^9$。

    题解:

    先简单的整理一下式子,所求式为

    $f_{d}(n)=sum limits_{i=1}^{n}{[(i,n)=1] imes i^{d}}$

    $=sum limits_{i=1}^{n}{i^{d} sum limits_{c|(i,n)}{mu(c)}}$

    $=sum limits_{c|n}{mu(c) sum limits_{i=1}^{frac{n}{c}}{(ic)^{d}}}$

    $=sum limits_{c|n}{mu(c)c^{d} sum limits_{i=1}^{frac{n}{c}}{i^{d}}}$

    根据伯努利数那套推论,$sum limits_{i=1}^{n}{i^{d}}$是一个以n为自变量的d+1次函数(多项式)。

    于是我们先用$Lagrange$插值把这个多项式的系数插出来,设其为$F(x)=sum limits_{i=0}^{d+1}{f_i x^{i}}$。

    然后继续推,所求式为

    $=sum limits_{c|n}{mu(c)c^{d}F(frac{n}{c})}$

    $=sum limits_{c|n}{mu(c)c^{d} sum limits_{i=0}^{d+1}{f_i (frac{n}{c})^{i}}}$

    $=sum limits_{i=0}^{d+1}{f_i sum limits_{c|n}{mu(c)c^{d}(frac{n}{c})^{i}}}$

    根据狄利克雷卷积那套推论,如果$F(n)=sum limits_{d|n}{f(d)g(frac{n}{d})}$,且f和g都是积性函数,那么F也是积性函数。

    (积性函数:若$(a,b)=1$,则$F(ab)=F(a)F(b)$)

    观察一下,$mu(c),c^{d},(frac{n}{c})^{i}$都是积性函数。

    于是我们只需要算每个$n=p_{i}^{a_{i}}$处的$sum limits_{c|n}{mu(c)c^{d}(frac{n}{c})^{i}}$,然后乘起来即可。

    注意到$mu(c)$只在$c=1,p_{i}$的时候不为0,所以有用的c就俩值,直接暴力算即可。

    由于$dleq 100$,算$f_i$的时候直接暴力算即可,总复杂度$O(d^{3}+dwlog{a_{i}})$。

    (注意快速幂的时候一定不要把次数取模,不要把次数取模,不要把次数取模!TAT)

    套路:

    • $sum limits_{i=1}^{n}{i^{d}}$是一个以n为自变量的d+1次函数。
    • 如果$F(n)=sum limits_{d|n}{f(d)g(frac{n}{d})}$,且f和g都是积性函数,那么F也是积性函数。
    • 快速幂时:一定不要把次数取模,不要把次数取模,不要把次数取模!

    代码:

    #include<bits/stdc++.h>
    #define maxn 205
    #define maxm 500005
    #define inf 0x7fffffff
    #define mod 1000000007
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    struct point{ll x,y;}P[maxn];
    struct poly{
        ll a[maxn],n;
        inline void clear(){memset(a,0,sizeof(a)),n=0;}
        poly operator+(const poly b)const{
            poly res; res.clear(),res.n=max(n,b.n);
            for(ll i=0;i<res.n;i++) res.a[i]=(a[i]+b.a[i])%mod;
            return res;
        }
        poly operator*(const poly b)const{
            poly res; res.clear(),res.n=n+b.n-1;
            for(ll i=0;i<n;i++)
                for(ll j=0;j<b.n;j++)
                    res.a[i+j]=(res.a[i+j]+a[i]*b.a[j]%mod)%mod;
            return res;
        }
        poly operator^(const ll b)const{
            poly res; res.clear(),res.n=n;
            for(ll i=0;i<res.n;i++) res.a[i]=a[i]*b%mod;
            return res;
        }
    };
    ll p[maxm],al[maxm];
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline ll pw(ll a,ll b){ll r=1;while(b)r=(b&1)?r*a%mod:r,a=a*a%mod,b>>=1;return r;}
    inline ll inv(ll x){if(x<0) x+=mod; return pw(x,mod-2);}
    
    inline poly Lagrange(ll n){
        for(ll i=1;i<=n+2;i++)
            P[i].x=i,P[i].y=(P[i-1].y+pw(i,n))%mod;
        poly res; res.clear();
        for(ll i=1;i<=n+2;i++){
            poly f; f.clear(),f.n=1,f.a[0]=1;
            for(ll j=1;j<=n+2;j++){
                if(i==j) continue;
                ll xi=P[i].x,xj=P[j].x,yj=P[j].y;
                poly g; g.clear(),g.n=2; 
                g.a[0]=xj*inv(xj-xi)%mod;
                g.a[1]=inv(xi-xj)%mod,f=f*g;
            }    
            res=res+(f^P[i].y);
        }
        return res;
    }
    
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("sol.out","w",stdout);
        ll d=read(),w=read(); 
        poly f=Lagrange(d);
        for(ll i=1;i<=w;i++) p[i]=read(),al[i]=read();
        ll ans=0;
        for(ll i=0;i<=d+1;i++){
            ll gi=1;
            for(ll j=1;j<=w;j++){
                ll t1=pw(p[j],al[j]*i);
                ll t2=mod-pw(p[j],(d+(al[j]-1)*i));
                gi=gi*(t1+t2)%mod;
            }
            ans=(ans+gi*f.a[i]%mod)%mod;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    一个人的数论
  • 相关阅读:
    Spring2.5.6学习笔记DI的两种注入方式
    hsqldb2.2.9文档学习笔记之使用hsqldb
    Spring2.5.6学习笔记实例化bean的几种方法
    eclipse4.2插件开发之Hello!EclipsePlugin
    spring boot redis 多数据源配置 spring boot data redis
    docker安装mysql
    docker安装rabbitmq
    docker命令积累
    mysql8 免安装版 下载安装
    docker安装nginx
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13257691.html
Copyright © 2011-2022 走看看