zoukankan      html  css  js  c++  java
  • 6545. 【GDOI2020模拟4.8】USACO 2020 Open Contest, Platinum(exercise)

    题目描述

    Farmer John(又)想到了一个新的奶牛晨练方案! 如同之前,Farmer John 的 N 头奶牛( 1 ≤ N ≤ 7500 )站成一排。对于 1 ≤ i ≤ N 的每一个 i ,从左往右第 i 头奶牛的编号为 i 。他告诉她们重复以下步骤,直到奶牛们与她们开始时的顺序相同。给定长为 N 的一个排列 A ,奶牛们改变她们的顺序,使得在改变之前从左往右第 i 头奶牛在改变之后为从左往右第 A i 头。 例如,如果A=(1,2,3,4,5),那么奶牛们总共进行一步就回到了同样的顺序。如果A=(2,3,1,5,4),那么奶牛们总共进行六步之后回到起始的顺序。每步之后奶牛们从左往右的顺序如下:
    计算所有可能的 N ! 种长为 N 的排列 A 回到起始顺序需要的步数的乘积。

    n<=7500

    题解

    直接算的话lcm太大了,考虑算p^k的贡献

    (huge ans=prod{p^{sum{f(p^k)}}})

    其中f(x)表示至少存在一个长度为x的倍数的环的方案数

    容斥一下,系数为(-1)^环的个数

    每次硬点当前环的开头为1号点,剩下的组合数排一下,最后乘上(环长-1)!表示环的连边方案

    时间为(sum{(frac{n}{x})^2}),其中(sum{frac{1}{x^2}}=frac{pi^2}{6}),所以时间为O(n^2)

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    #define file
    using namespace std;
    
    ll jc[7501],C[7501][7501],g[7501],s,ans;
    int p[7501],n,mod,i,j,k,l,len;
    bool f[7501];
    
    ll qpower(ll a,int b) {ll ans=1;while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
    
    void init()
    {
    	int i,j,k,l;
    	
    	fo(i,2,n)
    	{
    		if (!f[i]) p[++len]=i;
    		
    		fo(j,1,len)
    		if (i*p[j]<=n)
    		{
    			f[i*p[j]]=1;
    			if (!(i%p[j])) break;
    		}
    		else break;
    	}
    }
    
    ll js(int s)
    {
    	int N=n/s,i,j,k,l;
    	ll sum=0;
    	
    	memset(g,0,(N+1)*8);g[0]=1;
    	fo(i,1,N)
    	{
    		fo(j,1,i)
    		g[i]=(g[i]-g[i-j]*C[i*s-1][j*s-1]%(mod-1)*jc[j*s-1])%(mod-1);
    	}
    	
    	fo(i,0,N) sum=(sum+g[i]*C[n][i*s]%(mod-1)*jc[n-i*s])%(mod-1);
    	return (jc[n]-sum)%(mod-1);
    }
    
    int main()
    {
    	freopen("exercise.in","r",stdin);
    	#ifdef file
    	freopen("exercise.out","w",stdout);
    	#endif
    	
    	scanf("%d%d",&n,&mod);init();
    	jc[0]=1;fo(i,1,n) jc[i]=jc[i-1]*i%(mod-1);
    	fo(i,1,n)
    	{
    		C[i][0]=C[i][i]=1;
    		fo(j,1,i-1) C[i][j]=(C[i-1][j]+C[i-1][j-1])%(mod-1);
    	}
    	
    	ans=1;
    	fo(i,1,len)
    	{
    		for (s=0,j=p[i]; j<=n; j*=p[i]) s=(s+js(j))%(mod-1);
    		ans=ans*qpower(p[i],(s+mod-1)%(mod-1))%mod;
    	}
    	printf("%lld
    ",ans);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    C#与JS实现 获取指定字节长度 中英文混合字符串 的方法
    CKFinder_AspDotNet_2.4 破解方法 去版权
    MVC3中如何输出富文本
    CKEditor与CKFinder整合 MVC3
    vue项目多页配置
    设备宽度
    h5前端项目常见问题汇总
    react分享
    javascript-复制
    vue开发笔记
  • 原文地址:https://www.cnblogs.com/gmh77/p/12684538.html
Copyright © 2011-2022 走看看