【BZOJ5298】[CQOI2018]交錯序列(動態規划,矩陣快速冪)


【BZOJ5298】[CQOI2018]交錯序列(動態規划,矩陣快速冪)

題面

BZOJ
洛谷

題解

考慮由\(x\)\(1\)\(y\)\(0\)組成的合法串的個數。
顯然就是把\(1\)當做隔板插入進去,那么有\(y+1\)個位置可以放\(1\),所以方案數就是\({y+1\choose x}\)
\(x^ay^b\)的貢獻可以直接快速冪算,所以問題變成了求組合數。然后\(Lucas\)一下就可以得到\(TLE\)的好成績了。復雜度\(O(nlogn)\)(事實上只要有快速冪就會\(T\)

那就換種做法吧。。。來\(dp\)
\(x^ay^b\)展開其中一個部分,即\((n-y)^ay^b\),大力展開之后變成了\(\displaystyle y^b\sum_{i=0}^a{a\choose i}(-y)^{a-i}n^{i}\)。再化簡一下就是\(\displaystyle \sum_{i=0}^a{a\choose i}(-1)^{a-i}y^{a+b-i}n^i\),因此只需要對於每一個\(i\),求\(y^{a+b-i}\)的和就好了。
\(f[i][j][0/1]\)表示現在考慮到了第\(i\)位,這一位填的數是\(0/1\)的特征值的\(j\)次方和。
那么這樣子考慮在這一位上填上了一個\(1\),那么\(y^j\)變成了\((y+1)^j\),二項式定理展開+做差之后,得到的就是\((y+1)^j=\sum_{i=0}^{j} {j\choose i}y^i\)
這樣子就可以使用矩乘來進行轉移,時間復雜度大概是\(O((2(a+b+1))^3log)\)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 10000100
int a,b,n,N,ans,MOD,C[200][200],pw[200];
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
struct Matrix
{
	int s[200][200];
	void clear(){memset(s,0,sizeof(s));}
	void pre(){clear();for(int i=0;i<N;++i)s[i][i]=1;}
	int*operator[](int x){return s[x];}
}G;
Matrix operator*(Matrix &a,Matrix &b)
{
	Matrix ret;ret.clear();
	for(int i=0;i<N;++i)
		for(int k=0;k<N;++k)
			if(a[i][k])
				for(int j=0;j<N;++j)
					ret[i][j]=(ret[i][j]+1ll*a[i][k]*b[k][j])%MOD;
	return ret;
}
Matrix fpow(Matrix a,int b)
{
	Matrix s;s.clear();s[0][0]=1;
	while(b){if(b&1)s=s*a;a=a*a;b>>=1;}
	return s;
}
int main()
{
	scanf("%d%d%d%d",&n,&a,&b,&MOD);
	for(int i=0;i<=a+b;++i)C[i][0]=1;
	for(int i=1;i<=a+b;++i)
		for(int j=1;j<=i;++j)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
	pw[0]=1;for(int i=1;i<=a+b;++i)pw[i]=1ll*pw[i-1]*n%MOD;
	int l=a+b+1;N=l<<1;
	for(int i=0;i<=a+b;++i)
	{
		G[i+l][i]=G[i][i]=1;
		for(int j=0;j<=i;++j)G[j][i+l]=C[i][j];
	}
	Matrix A=fpow(G,n);
	for(int i=0,d=(a&1)?MOD-1:1;i<=a;++i,d=MOD-d)
		ans=(ans+1ll*C[a][i]*d%MOD*(A[0][a+b-i]+A[0][a+b-i+l])%MOD*pw[i])%MOD;
	printf("%d\n",ans);
	return 0;	
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM