zoukankan      html  css  js  c++  java
  • #莫比乌斯反演,整除分块,欧拉定理#U137539 虚伪的最小公倍数

    题目

    [largeprod_{i_1=1}^nprod_{i_2=1}^ndotsprod_{i_k=1}^nfrac{i_1*i_2*dots*i_k}{gcd(i_1,i_2,dots,i_k)}pmod {998244353} ]


    分析

    考虑分子分母分别处理,首先看分子,设

    [large f[k]=prod_{i_1=1}^nprod_{i_2=1}^ndotsprod_{i_k=1}^n i_1*i_2*dots*i_k ]

    那么(f[k]=(n!)^{n^{k-1}}f[k-1]^n),其中(f[0]=1)
    (f_n[k])表示(f[k])(n!)的次数,那么
    (f_n[k]=n^{k-1}+n*f_n[k-1]),其中(f_n[0]=0)
    可以找规律发现(f_n[k]=kn^{k-1})
    那么

    [f[k]=(n!)^{kn^{k-1}} ]

    这就是分子
    分母就是

    [largeprod_{i_1=1}^nprod_{i_2=1}^ndotsprod_{i_k=1}^n gcd(i_1,i_2,dots,i_k) ]

    如果硬套性质很难做,考虑枚举约数计算这个约数出现了多少次,那也就是

    [large prod_{d=1}^n d^{sum_{i_1=1}^{lfloorfrac{n}{d} floor}sum_{i_2=1}^{lfloorfrac{n}{d} floor}dots sum_{i_k=1}^{lfloorfrac{n}{d} floor}[gcd(i_1,i_2,dots i_k)==d]} ]

    根据莫比乌斯函数的性质化简得到

    [large prod_{d=1}^n d^{sum_{g=1}^frac{n}{d}mu(g){lfloorfrac{n}{dg} floor}^k} ]

    如果直接套用整除分块会TLE,考虑预处理({lfloorfrac{n}{dg} floor}^k)
    一定要做到(O(1))查询,这个很简单,直接开个桶完成一次询问后清除标记就可以了
    如果用个STL::map的话就会TLE,当然可以套用欧拉定理优化快速幂


    代码

    #include <cstdio>
    #include <cctype>
    #include <map>
    #define rr register
    using namespace std;
    const int mod=998244353,phi=998244352,Phi=402653184,P=3001;
    const int N=300000; typedef long long lll; lll k; int h[N|31];
    int mu[N|31],fac[N|31],inv[N|31],prime[N|31],Cnt,v[N|31],ans,T,n;
    inline signed ksm(int x,int y,int p){
    	rr int ans=1;
    	for (;y;y>>=1,x=1ll*x*x%p)
    		if (y&1) ans=1ll*ans*x%p;
    	return ans; 
    }
    signed main(){
    	mu[1]=fac[0]=fac[1]=inv[0]=inv[1]=1;
    	for (rr int i=2;i<=N;++i){
    		if (!v[i]) prime[++Cnt]=i,mu[i]=-1;
    		for (rr int j=1;j<=Cnt&&prime[j]<=N/i;++j){
    			v[i*prime[j]]=1;
    			if (i%prime[j]==0) break;
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for (rr int i=2;i<=N;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod,mu[i]+=mu[i-1];
    	for (rr int i=2;i<=N;++i) fac[i]=1ll*fac[i-1]*i%mod,inv[i]=1ll*inv[i-1]*inv[i]%mod;
    	for (scanf("%d",&T);T;--T){
    		scanf("%d%lld",&n,&k),ans=1;
    		rr int f=ksm(fac[n],1ll*k%phi*ksm(n,(k-1)%Phi,phi)%phi,mod);
    		for (rr int l=1,r,z;l<=n;l=r+1)
    			z=n/l,r=n/z,h[z]=ksm(z,k%Phi,phi);
    		for (rr int l=1,r,z,now;l<=n;l=r+1){
    			z=n/l,r=n/z,now=0;
    			for (rr int L=1,R,Z;L<=z;L=R+1)
    				Z=z/L,R=z/Z,now=(now+1ll*(mu[R]-mu[L-1]+phi)*h[Z]%phi)%phi;
    			ans=1ll*ans*ksm(1ll*fac[r]*inv[l-1]%mod,now,mod)%mod;
    		}
    		for (rr int l=1,r,z;l<=n;l=r+1)
    			z=n/l,r=n/z,h[z]=0;
    		printf("%lld
    ",1ll*f*ksm(ans,mod-2,mod)%mod);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    python3 crypto winrandom import error
    Flask-Babel 中文支持(zh-CN和zh-Hans-CN)
    pip 安装psycopg的错误
    Aapache status / apache2ctl status 总是403
    为什么你还在用嵌入式的方式来使用mod_wsgi?
    Git中当add错误的时候怎么办?
    Python 内置彩蛋
    本人AI知识体系导航
    本人SW知识体系导航
    SSH密钥对登录的原理和实践
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13892799.html
Copyright © 2011-2022 走看看