• [机房测试] Lcm


    Description

    \(T\leq 10^3\) 次询问,求

    \[(*)=\prod_{i_1=1}^n \prod_{i_2=1}^n\dots\prod_{i_k=1}^n \frac{i_1i_2\dots i_k}{\gcd(i_1,i_2,\dots,i_k)} \]

    其中 \(n\leq 3\times 10^5\)\(k\leq 10^{18}\)

    Solution

    \[(*)=\frac{(n!)^{kn^{k-1}}}{\prod_{d=1}^n d^{f(d)}} \]

    其中 \(f(d)\)\(\gcd=d\) 的方案数。设 \(g(d)\) 表示 \(d|\gcd\) 的方案数,则有

    \[\begin{align} f(d)&=\sum_{d|i} \mu(\frac{i}{d})g(i)\\ g(d)&=\lfloor \frac{n}{d} \rfloor ^k \end{align} \]

    这样就得到一个 \(O(Tn\log n\log k)\) 的做法。预处理快速幂,可以做到 \(O(Tn\log n)\)

    合并并化简,可以得到

    \[f(d)=\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor} \mu(i) \lfloor \frac{\lfloor\frac{n}{d}\rfloor}{i} \rfloor^k \]

    可以发现,\(f(d)\) 只有 \(\sqrt n\) 种取值,\(f(d)\) 的内和也是同理的。运用整除分块嵌套,可以做到 \(O(Tn^{\frac{3}{4}}\log k)\)

    再次观察,有

    \[\lfloor \frac{\lfloor\frac{n}{d}\rfloor}{i} \rfloor=\lfloor \frac{n}{id} \rfloor \]

    所以这两个表达式所有取值组成的集合是相同的,预处理所有 \(\lfloor \frac{n}{d} \rfloor\) 的幂,可以做到 \(O(Tn^{\frac{3}{4}})\).

    #include<stdio.h>
    #include<cassert>
    
    typedef long long ll;
    
    const int N=3e5+7;
    const int Mod=998244353;
    
    inline ll read(){
        ll x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')flag=1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
    
    bool mk[N];
    ll fac[N],ifac[N],K,pw[N];
    int mu[N],p[N],pn=0,n;
    
    ll qpow(ll x,ll y,int mod){
        ll ret=1;
        while(y){
            if(y&1) ret=ret*x%mod;
            x=x*x%mod,y>>=1;
        }
        return ret;
    }
    
    inline ll f(int x){
        ll ret=0;
        for(int l=1,r=0;l<=x;l=r+1)
            r=x/(x/l),ret=(ret+(mu[r]-mu[l-1])*pw[x/l]%(Mod-1)+(Mod-1))%(Mod-1);
        return ret;
    }
    
    int main(){
        int T=read(); fac[0]=1,mu[1]=1;
        for(int i=1;i<N;i++) fac[i]=fac[i-1]*i%Mod;
        ifac[N-1]=qpow(fac[N-1],Mod-2,Mod);
        for(int i=N-2;~i;i--) ifac[i]=ifac[i+1]*(i+1)%Mod;
        for(int i=2;i<N;i++){
            if(!mk[i]) p[++pn]=i,mu[i]=-1;
            for(int j=1;j<=pn&&p[j]*i<N;j++){
                mk[p[j]*i]=1; if(i%p[j]==0) break;
                mu[p[j]*i]=-mu[i];
            }
        }
        for(int i=2;i<N;i++) mu[i]+=mu[i-1];
        while(T--){
            n=read(); K=read();
            ll ans=qpow(fac[n],(K%(Mod-1))*qpow(n,K-1,Mod-1)%(Mod-1),Mod),ret=1;
            for(int l=1,r=0;l<=n;l=r+1)
                r=n/(n/l),pw[n/l]=qpow(n/l,K,Mod-1);
            for(int l=1,r=0;l<=n;l=r+1)
                r=n/(n/l),ret=ret*qpow(fac[r]*ifac[l-1]%Mod,f(n/l),Mod)%Mod;
            printf("%lld\n",ans*qpow(ret,Mod-2,Mod)%Mod);
        }
    }
    
  • 相关阅读:
    android笔记5——同一个Activity中Fragment的切换
    JavaScript 刚開始学习的人应知的 24 条最佳实践
    位运算符之异或的化腐朽为奇妙
    unity常见问题之20题
    汉澳sinox不受openssl心血漏洞影响并分析修复其漏洞代码
    基于canvas和Web Audio的音频播放器
    poj2595(凸包)
    HDU 1257 最少拦截系统(dp)
    【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容
    万能狗! 程序猿屌丝独自创业之路(一)
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15545329.html
Copyright © 2020-2023  润新知