P5520 [yLOI2019] 青原樱

Posted may-2nd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P5520 [yLOI2019] 青原樱相关的知识,希望对你有一定的参考价值。

部分分比较多,依次讲一讲。

因为带编号,所以最后答案要乘上 (m!)

对于子任务 1,直接输出 1%p,时间复杂度 (O(1))

对于子任务 2,dfs 枚举每个位置是否种植,时间复杂度 (O(2^n))

对于子任务 3,设 (f_{i,j}) 为种了 (i) 株幼苗,最后一株种在位置 (j) 的方案数。

[f_{i,j}=sum_{k<j-1}f_{i-1,k} ]

直接转移即可,时间复杂度 (O(n^2m))

对于子任务 4,易发现子任务 3 中的 DP 可以用前缀和优化到 (O(nm))

对于子任务 5,我们发现 DP 难以解决了,因为状态无论如何都高达 (nm),于是可以考虑组合数直接计算。

考虑合法的方案,相邻的两株幼苗之间至少有一个空位。

拉出 (m-1) 个空位,剩下 (n-m+1) 个位置随便种,然后在每两株幼苗之间插入一个空位,这样一定是合法且唯一的。

所以总方案数就是 (inom{n-m+1}{m}),因为模数是质数所以可以用逆元做,时间复杂度 (O(n+log p))

对于子任务 6,发现最终的答案就是 (inom{n-m+1}{m} imes m!=frac{(n-m+1)!m!}{m!(n-m+1-m)!}=frac{(n-m+1)!}{(n+1-2m)!}=A_{n-m+1}^m)

直接算,时间复杂度 (O(m))

code:

#include<bits/stdc++.h>
using namespace std;
#define N 2005
#define Max(x,y)((x)>(y)?x:y)
#define For(i,x,y)for(i=x;i<=(y);i++)
int n,m,p;
namespace Subtask1
{
	inline void init()
	{
		cout<<1%p;
	}
}
namespace Subtask2
{
	int tot;
	void dfs(int pos,int num)
	{
		if(pos>n)
		{
			if(!num)tot++;
			return;
		}
		dfs(pos+1,num);
		if(num)dfs(pos+2,num-1);
	}
	void init()
	{
		int i;
		dfs(1,m);
		For(i,2,m)tot*=i;
		cout<<tot%p;
	}
}
namespace Subtask3
{
	int f[205][405],tot;
	void init()
	{
		int i,j,k;
		f[0][0]=1;
		For(i,1,m)
		For(j,(i<<1)-1,n)
		For(k,Max((i<<1)-3,0),Max(j-2,0))f[i][j]=(f[i][j]+f[i-1][k])%p;
		For(i,(m<<1)-1,n)tot=(tot+f[m][i])%p;
		For(i,2,m)tot=1LL*tot*i%p;
		cout<<tot;
	}
}
namespace Subtask4
{
	int f[N][N];
	void init()
	{
		int i,j;
		For(i,0,n)f[0][i]=1;
		For(i,1,m)
		For(j,(i<<1)-1,n)f[i][j]=(f[i][j-1]+f[i-1][Max(j-2,0)]-(!Max((i<<1)-3,0)?0:f[i-1][Max((i<<1)-3,0)-1]))%p;
		For(i,2,m)f[m][n]=1LL*f[m][n]*i%p;
		cout<<f[m][n];
	}
}
namespace Subtask5
{
	int tot=1;
	int ksm(int x,int y)
	{
		return(!y?1:1LL*ksm(1LL*x*x%p,y>>1)*(y&1?x:1)%p);
	}
	int C(int x,int y)
	{
		int tmp=1,i;
		For(i,2,y)tmp=1LL*tmp*i%p;
		For(i,2,x-y)tmp=1LL*tmp*i%p;
		tmp=ksm(tmp,p-2);
		For(i,2,x)tmp=1LL*tmp*i%p;
		return tmp;
	}
	void init()
	{
		int i;
		For(i,2,m)tot=1LL*tot*i%p;
		cout<<1LL*C(n-m+1,m)*tot%p;
	}
}
namespace Subtask6
{
	int P(int x,int y)
	{
		int tot=1;
		while(y--)tot=1LL*tot*x--%p;
		return tot;
	}
	inline void init()
	{
		cout<<P(n-m+1,m);
	}
}
int main()
{
	int type;
	cin>>type>>n>>m>>p;
	switch(type)
	{
		case 0:Subtask1::init();
		break;
		case 1:Subtask2::init();
		break;
		case 2:Subtask3::init();
		break;
		case 3:Subtask4::init();
		break;
		case 4:Subtask5::init();
		break;
		case 5:Subtask6::init();
		break;
	}
	return 0;
}

分包写了,应该很清楚吧 qwq。

以上是关于P5520 [yLOI2019] 青原樱的主要内容,如果未能解决你的问题,请参考以下文章

青原樱(组合数学)

yLOI2018锦鲤抄

《百变小樱》结尾曲《gnovy》

百变小樱的一篇文章的地址,急求。

谁有关于百变小樱的片尾曲歌词(中文)

《百变小樱》动画版中片尾曲叫啥名字? 就是那个“滴答,友情无时不甜美,就像水果那样新鲜”