• Luogu P4902 乘积


    题目
    我们要求的是

    [prodlimits_{i=a}^bprodlimits_{j=1}^i(frac ij)^{lfloorfrac ij floor} ]

    先把它拆开

    [prodlimits_{i=a}^bprodlimits_{j=1}^ii^{lfloorfrac ij floor}(frac1{prodlimits_{i=a}^bprodlimits_{j=1}^ij^{lfloorfrac ij floor}}) ]

    对于右边,我们把(jin[1,i])换成(jin[1,b])是没有任何问题的。因为(forall jin(i,b],lfloorfrac ij floor=0),相当于多乘了几个(1)
    然后再交换右边的连乘符号

    [prodlimits_{i=a}^bprodlimits_{j=1}^ii^{lfloorfrac ij floor}(frac1{prodlimits_{j=1}^bprodlimits_{i=a}^bj^{lfloorfrac ij floor}}) ]

    我们把连乘换成指数的求和

    [prodlimits_{i=a}^bi^{sumlimits_{j=1}^ilfloorfrac ij floor}(frac1{prodlimits_{j=1}^bj^{sumlimits_{i=a}^blfloorfrac ij floor}}) ]

    然后容斥一下

    [prodlimits_{i=1}^bi^{sumlimits_{j=1}^ilfloorfrac ij floor}prodlimits_{j=1}^{a-1}j^{sumlimits_{i=1}^{a-1}lfloorfrac ij floor}(frac1{prodlimits_{j=1}^bj^{sumlimits_{i=1}^blfloorfrac ij floor}prodlimits_{i=1}^{a-1}i^{sumlimits_{j=1}^ilfloorfrac ij floor}}) ]

    [let a=a-1,f(n)=prodlimits_{i=1}^ni^{sumlimits_{j=1}^ilfloorfrac ij floor},g(n)=prodlimits_{j=1}^nj^{sumlimits_{i=1}^nlfloorfrac ij floor} ]

    则要求的式子就变成了

    [f(b)g(a)(frac1{f(a)g(b)}) ]

    所以如果我们能够以(O(nlog n))的复杂的筛出(f,g)的话就能解决问题。
    首先计算(f)

    [let sigma(n)=sumlimits_{d|n}1,d(n)=sumlimits_{i=1}^nsigma(i) ]

    考虑到枚举约数和枚举倍数的等价性

    [d(n)=sumlimits_{i=1}^nlfloorfrac ni floor ]

    [f(n)=prodlimits_{i=1}^ni^{d(i)} ]

    显然其递推式为

    [f(n)=f(n-1)n^{d(n)} ]

    所以我们可以(O(nlog n))筛出(sigma)即除数函数,然后前缀和求出,(d),再按递推式求出(f)
    注意(d)是作为指数存在,所以取模时需要对(P-1)取模。
    再计算(g)

    [let t(n)=frac{g(n)}{g(n-1)}=prodlimits_{i=1}^ni^{lfloorfrac ni floor},h(n)=frac{t(n)}{t(n-1)}=prodlimits_{d|n}d ]

    显然我们可以(O(nlog n))筛出(h)即约数积函数,然后做两遍前缀积就可以得到(g)

    #include<bits/stdc++.h>
    using namespace std;
    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
        void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
        void Put(char x){*oS++=x;if(oS==oT)Flush();}
        int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('
    ');}
    }
    using namespace IO;
    const int N=1000007,A=1000000,P=993244853;
    int inc(int a,int b,int p=P){a+=b;return a>=p? a-p:a;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int power(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int d[N],s[N],f[N];
    int main()
    {
        int i,j,n,a,b;
        s[0]=f[0]=1;
        for(i=1;i<=A;++i) s[i]=1;
        for(i=1;i<=A;++i) for(j=i;j<=A;j+=i) ++d[j],s[j]=mul(s[j],i);
        for(i=1;i<=A;++i) d[i]=inc(d[i],d[i-1],P-1),f[i]=mul(f[i-1],power(i,d[i])),s[i]=mul(s[i],s[i-1]);
        for(i=1;i<=A;++i) s[i]=mul(s[i],s[i-1]);
        for(n=read();n;--n) a=read()-1,b=read(),write(mul(mul(mul(power(f[a],P-2),f[b]),power(s[b],P-2)),s[a]));
        return Flush(),0;
    }
    
  • 相关阅读:
    BZOJ 1800 [Ahoi2009]fly 飞行棋
    BZOJ 3309 DZY Loves Math
    CAS Server和client 实现单点登录
    单点登录原理与简单实现
    Maven插件
    win10安装最新nexus-3.x及maven简单配置介绍
    oracle获取表的属性,包括字段,注释
    java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
    深入理解Tomcat虚拟目录
    环境搭建系列-系统安装之centos 6.5安装与配置
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11914028.html
Copyright © 2020-2023  润新知