zoukankan      html  css  js  c++  java
  • 「FJWC2020Day5-zzq」lg (容斥)

    「FJWC2020Day5-zzq」lg

    设模数为(P)

    考虑对于每一个(gcd)计算( ext{lcm})之积(F(m))

    那么可以想到强制每个数都是(gcd)的倍数,问题转化为求(lfloor frac{m}{gcd} floor) 以内所有( ext{lcm})的积(G(m))

    那么对于每个质因数依次考虑,则得到一个简单的式子

    [G(m)=egin{aligned}prod p_i^{sum_{j=1}m^n-(m-lfloor frac{m}{p_i^j} floor )^n} end{aligned} ]

    (如果看不清可以放大页面)

    其中枚举的(j)(p_i)至少出现(j)次的方案数,枚举的(j)(log m) 级别的

    肯定是先求出指数(mod varphi(P)),可以线性预处理出所有的(i^n mod varphi(P))

    对于每个(p_i)求出指数后还要快速幂,复杂度就是(O(pi(m)log P)=O(m))(其中(pi(m))(m)以内的质数个数),实际带有一些常数

    那么求(G(m))的复杂度上界是(O(mlog m)),实际上$lfloor frac{m}{i} floor $有很多重复,复杂度要低很多

    得到的每个(gcd)的答案还要把强制取出的(gcd)补上,是(gcd^{{lfloor frac{m}{gcd} floor }^n})

    那么对于(G(m))枚举倍数进行容斥的到(F(m))即可,需要求每个(F(m))的逆元,复杂度是(O(m(log P+log m)))

    总复杂度的上界就是(O(mlog P))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    enum{N=200010,P=998244353,Phi=P-1};
    int n,m,p[N],mk[N],g[N],ig[N],h[N];
    ll qpow(ll x,ll k,ll P) {
    	ll res=1;
    	for(;k;k>>=1,x=x*x%P) if(k&1) res=res*x%P;
    	return res;
    }
    int G(int m) {
    	if(h[m]) return h[m];
    	ll ans=1;
    	rep(i,2,m) if(!mk[i]) {
    		ll d=1,s=0;
    		for(;(d*=i)<=m;) s+=p[m]-p[m-m/d]; // 带入上式求出答案
    		ans=ans*qpow(i,(s%Phi+Phi)%Phi,P)%P;
    	}
    	return h[m]=ans;
    }
    int main(){
    	freopen("lg.in","r",stdin),freopen("lg.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	rep(i,2,N-1) if(!mk[i]) for(int j=i+i;j<N;j+=i) mk[j]=1;
    	rep(i,0,m) p[i]=qpow(i,n,Phi); // 预处理出i^n mod Phi
    	rep(i,1,m) g[i]=G(m/i)*qpow(i,p[m/i],P)%P; // 注意要补上
    	ll ans=1;
    	for(int i=m;i;i--){
    		for(int j=i+i;j<=m;j+=i) g[i]=1ll*g[i]*ig[j]%P; // 容斥得到f
    		ig[i]=qpow(g[i],P-2,P),ans=ans*qpow(g[i],i,P)%P;
    	}
    	printf("%lld
    ",ans);
    }
    
    
    
    
  • 相关阅读:
    一次sqlldr性能测试案例
    Java过滤特殊字符的正则表达式
    朝阳自行成交过户流程
    direct=true 错误处理方法 (关于 Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法
    SQLLDR直接加载几个参数的测试
    处理超出打开游标的最大数异常(ORA01000: maximum open cursors exceeded)
    java 用PreparedStatement来setDate,用问号的形式给日期问号赋值
    linux下的文件结构介绍
    用SQLLDR来装载CLOB/BLOB列的控制文件例子
    关于oracle日期的说明
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13140959.html
Copyright © 2011-2022 走看看