[SDOI2010]地精部落 题解

题目传送门

题目大意

已知一个长度为 \(n\) 的排列 \(p_1,p_2,\dots,p_n\) 满足对于任意的 \(i\in \{2,3,\dots,n-1\}\) 都有 \(p_{i-1}<p_i>p_{i+1}\) 或者 \(p_{i-1}>p_i<p_{i+1}\) ,求满足条件的排列的数量除以 \(p\) 所得到的余数( \(p\) 不一定是质数 ).

题目解析

考虑 DP.
但是我们发现由于限制我们很难进行递推,所以我们设 \(f_i\) 代表选择 \(1,2,\dots,i\) 的个数,并且这些序列都必须满足第一个数字比第二个大。显然我们发现答案就是 \(f_n\times2\).
我们设第 \(i\) 个数字放在第 \(j\) 个位置.因为 \(i\) 是最大的数字,所以 \(j\) 一定是奇数. 而原来的 \(i-1\) 个数字我们可以任选 \(j\) 个放在前面,所以还要乘上 \(C_{i-1}^{j}\)
不难得到:

\[f_i=\sum_{j=1,j=2k+1,k\in Z}^{i-1}f_{j}\times f_{i-j-1}\times C^{j}_{i-1} \]

这样就可以做到 \(\Theta\left(n^2\right)\) 的时间复杂度了.
当然我们发现由于 \(p\) 不是质数,所以我们不能通过逆元来求解。并且我们发现如果直接用杨辉三角预处理的话会 MLE,所以我们需要滚动数组。(计算 \(f_i\) 的时候只需要知道 \(C_{i-1}^{0},C_{i-1}^{1},\dots,C_{i-1}^{i-1}\))这个时候空间复杂度就是 \(\Theta\left(n\right)\) 的。

代码:

#include<cstdio>
#define db double
#define pc putchar
#define U unsigned
#define ll long long
#define ld long double
#define ull unsigned long long
#define Me(a,b) memset(a,b,sizeof(a))
template<typename _T> _T mabs(_T a){ return a>0?a:-a; }
template<typename _T> _T mmax(_T a,_T b){ return a>b?a:b; }
template<typename _T> _T mmin(_T a,_T b){ return a<b?a:b; }
template<typename _T> void mswap(_T &a,_T &b){ _T tmp=a; a=b; b=tmp; return; }
template<typename _T> void print(_T x){ if(x<0) putchar('-'),x=-x;
	if(x>9) print(x/10); putchar((x%10)+48); return; }
#define EPS (1e-7)
#define INF (0x7fffffff)
#define LL_INF (0x7fffffffffffffff)
#define maxn 4239
#define Type int
using namespace std;
Type read(){
	char c=getchar(); Type s=0; int flag=0;
	while((c<'0'||c>'9')&&c!='-') c=getchar();
	if(c=='-') c=getchar(),flag=1;
	while('0'<=c&&c<='9'){ s=(s<<1)+(s<<3)+(c^48); c=getchar(); }
	if(flag) return -s; return s;
}
int n;
ll f[maxn],c[2][maxn],p;
int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	n=read(); p=read(); f[0]=f[1]=1; c[0][0]=c[1][0]=c[1][1]=1; int i,j;
	for(i=2;i<=n;i++){
		for(j=1;j<i;j+=2) f[i]+=f[j]*f[i-j-1]%p*c[(i-1)&1][j]%p,f[i]%=p;
		for(j=1;j<i;j++) c[i&1][j]=(c[(i-1)&1][j]+c[(i-1)&1][j-1])%p; c[i&1][i]=1;
	} print(f[n]*2%p); return 0;
}
posted @ 2021-11-16 20:05  jiangtaizhe001  阅读(25)  评论(0编辑  收藏  举报