zoukankan      html  css  js  c++  java
  • 「USACO 2020 US Open Platinum」Exercise

    对于一个排列,答案是每个轮换环长的 (operatorname{lcm})

    考虑对每个质数算贡献。

    [ans=prod_{p}p^{sum_{egeq 1}sum_{Tsubseteq{1,...,n},sum_{c_iin T}=n}e[max(ord_p(c_i))==e]} ]

    只要算 (p) 的指数上的式子 (mod p-1) 的结果。

    [egin{aligned} sum_{egeq 1}sum_{Tsubseteq{1,...,n},sum_{c_iin T}=n}e[max(ord_p(c_i))==e]&=sum_{egeq}sum_{Tsubseteq{1,...,n},sum_{c_iin T}=n}[max(ord_p(c_i))>=e]\ &=sum_{egeq 1}sum_{Tsubseteq{1,...,n},sum_{c_iin T}=n}sum_{Ssubseteq T}(-1)^{mid S mid +1}prod_{c_i in S}[p^e|c_i]\ &=sum_{egeq 1}sum_{Ssubseteq {1,...,n}}(-1)^{|S| +1}{n choose {|S|}}(n-|S|)!prod_{c_i in S}[p^e|c_i] end{aligned} ]

    枚举(e),对后面的式子dp,(dp_i) 表示有 (i) 个点的答案。设 (x=p^e)
    枚举 (i) 号点所在环的大小。(dp_i=-sum_{j=1}^i{{i-1} choose {j-1}}(j-1)!dp_{i-j}[x mid j])

    发现有用的dp值只有 (n/x) 个。

    枚举(p,e),总复杂度是 (O(sum_psum_e(frac{n}{p^e})^2)leq O(sum_{x=1}^{n}(frac{n}{x})^2)=O(n^2))

    // Author -- Frame
    
    #include<bits/stdc++.h>
    
    #define lowbit(x) ((x)&(-(x)))
    #define Finline __inline__ __attribute__ ((always_inline))
    #define DEBUG fprintf(stderr,"Running on Line %d in Function %s
    ",__LINE__,__FUNCTION__)
    #define SZ(x) ((int)x.size())
    #define mkpr std::make_pair
    #define pb push_back
    
    typedef long long ll;
    typedef unsigned int uint;
    typedef unsigned long long ull;
    typedef std::pair<int,int> pi;
    typedef std::pair<ll,ll> pl;
    
    const int inf=0x3f3f3f3f,Inf=0x7fffffff;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    Finline uint rnd()
    {
    	static uint seed=416;
    	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
    }
    template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
    template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
    template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
    template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
    template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
    template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
    template <typename _Tp>Finline void read(_Tp &x)
    {
    	char ch(getchar());
    	bool f(false);
    	while(ch<48||ch>57) f|=ch==45,ch=getchar();
    	x=ch&15,ch=getchar();
    	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
    	if(f) x=-x;
    }
    template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args){read(t);read(args...);}
    template <typename _Tp,typename... Args>Finline _Tp min(const _Tp &a,const _Tp &b,const Args &...args){return a<b?min(a,args...):min(b,args...);}
    template <typename _Tp,typename... Args>Finline _Tp max(const _Tp &a,const _Tp &b,const Args &...args){return a<b?max(b,args...):max(a,args...);}
    Finline int read_str(char *s)
    {
    	char ch(getchar());
    	while(ch==' '||ch=='
    '||ch=='
    ') ch=getchar();
    	char *tar=s;
    	*tar=ch,ch=getchar();
    	while(ch!=' '&&ch!='
    '&&ch!='
    '&&ch!=EOF) *(++tar)=ch,ch=getchar();
    	return tar-s+1;
    }
    
    const int N=7505;
    int mod;
    template<typename _Tp1,typename _Tp2>Finline void add(_Tp1 &a,_Tp2 b){(a+=b)>=mod&&(a-=mod);}
    template<typename _Tp1,typename _Tp2>Finline void sub(_Tp1 &a,_Tp2 b){(a-=b)<0&&(a+=mod);}
    struct FastMod{
    	typedef __uint128_t LLL;
    	ull b,m;
    	void init(ull b) {this->b=b,m=ull((LLL(1)<<64)/b);}
    	Finline ull operator()(ull a){
    		ull r=a-(ull)((LLL(m)*a)>>64)*b;
    		return r>=b?r-b:r;
    	}
    }M;
    int fac[N],dp[N],C[N][N];
    bool pr[N];
    int p[N],pos;
    void sieve()
    {
    	for(int i=2;i<N;++i)
    	{
    		if(!pr[i]) p[++pos]=i;
    		for(int j=1;j<=pos&&i*p[j]<N;++j)
    		{
    			pr[i*p[j]]=true;
    			if(!(i%p[j])) break;
    		}
    	}
    }
    ll ksm(ll a,ll b,ll mod)
    {
    	ll res=1;
    	while(b)
    	{
    		if(b&1) res=res*a%mod;
    		a=a*a%mod,b>>=1;
    	}
    	return res;
    }
    int main()
    {
    	sieve();
    	int n,P;read(n,P);mod=P-1;M.init(mod);
    	fac[0]=1;for(int i=1;i<=n;++i) fac[i]=M(1ll*fac[i-1]*i);
    	for(int i=0;i<=n;++i) for(int j=C[i][0]=1;j<=i;++j) C[i][j]=C[i-1][j-1],add(C[i][j],C[i-1][j]);
    	int ans=1;
    	for(int _=1;_<=pos&&p[_]<=n;++_)
    	{
    		int tmp=0;
    		for(int cur=p[_];cur<=n;cur*=p[_])
    		{
    			int cnt=n/cur;
    			memset(dp,0,(cnt+3)<<2);dp[0]=mod-1;
    			for(int i=1;i<=cnt;++i) for(int j=1;j<=i;++j) sub(dp[i],M(M(1ll*C[i*cur-1][j*cur-1]*fac[j*cur-1])*dp[i-j]));
    			for(int i=1;i<=cnt;++i) add(tmp,M(M(1ll*C[n][i*cur]*fac[n-i*cur])*dp[i]));
    		}
    		if(tmp) ans=1ull*ans*ksm(p[_],tmp,P)%P;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    react-webpack
    react
    重置手机过程
    运用 Node-RED 开发 LoRa 应用
    IBM Node-RED 安装与使用教程
    Node-RED 入门教程:简介
    Thingsboard 3.0 修改 Title、默认语言、主题颜色
    Thingsboard 3.0 通过 tb-gateway 网关接入 MQTT 设备教程
    Thingsboard 入门学习笔记:属性
    ThingsBoard 3.0 版本发布
  • 原文地址:https://www.cnblogs.com/Frame233/p/13442370.html
Copyright © 2011-2022 走看看