O(n^9) dp 过不去样例 2 求条,马蜂良好
查看原帖
O(n^9) dp 过不去样例 2 求条,马蜂良好
530468
_determination_楼主2025/1/21 16:22

rt。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=0x3f3f3f3f3f3f3f3f;
const int N=40,M=5e5+10;
void debug(string s){cerr << "debug " << s << endl;}
void debug(int x){cerr << "debug " << x << endl;}
#define endl '\n'
int n,mod;
int f[2][N][N][N*N][N];
int g1[N][N][N*N],g[N][N][N*N];
int jc[N*N],invj[N*N];
int fp(int x,int p)
{
	int ans=1;
	while(p)
	{
		if(p&1)ans=ans*x%mod;
		x=x*x%mod;
		p>>=1;
	}
	return ans;
}
void init()
{
	jc[0]=1;
	for ( int i = 1 ; i < N*N ; i++ )
		jc[i]=jc[i-1]*i%mod;
	for ( int i = 0 ; i < N*N ; i++ )
		invj[i]=fp(jc[i],mod-2);
}
int C(int n,int m)
{
	if(m<0||m>n)return 0;
	return jc[n]*invj[m]%mod*invj[n-m]%mod;
}
int ans[N*N];
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin >> n >> mod;
	init();
	for ( int i = 1 ; i <= n ; i++ )
		g1[0][i][0]=1;
	for ( int i = 1 ; i <= n ; i++ )
		for ( int j = 1 ; j <= n-i ; j++ )
			for ( int k = i ; k <= min(n*(n-1)/2,i*j) ; k++ )
			{
				for ( int l = 1 ; l <= j ; l++ )
					g1[i][j][k]+=g1[i-1][j][k-l]*C(j,l)%mod;
				g1[i][j][k]%=mod;
				printf("g1[%d][%d][%d]=%d\n",i,j,k,g1[i][j][k]);
			}
	for ( int i = 1 ; i <= n ; i++ )
		for ( int j = 1 ; j <= n-i ; j++ )
			for ( int k = i ; k <= min(n*(n-1)/2,i*j+i*(i-1)/2) ; k++ )
			{
				for ( int l = 0 ; l <= min(i*(i-1)/2,k-i) ; l++ )
					g[i][j][k]+=g1[i][j][k-l]*C(i*(i-1)/2,l);
				g[i][j][k]%=mod;
				printf("g[%d][%d][%d]=%d\n",i,j,k,g[i][j][k]);
			}
//	debug("Test");
//	cerr << "debu" << endl;
//	cout << g1[3][2][5] << endl;
//	cout << g[3][2][5] << "\n";
	f[0][0][1][0][1]=1;
	for ( int i = 1 ; i < n ; i++ )
	{
		for ( int j = 1 ; j <= n ; j++ )
			for ( int k = 1 ; k <= (n-j) ; k++ )
				for ( int m = 1 ; m <= min((j+k)*(j+k-1)/2,n*(n-1)/2) ; m++ )
					for ( int lst = 1 ; lst <= j+k ; lst++ )
					{
						if(i%2==1&&j<lst)break;
						if(i%2==0&&k<lst)break;
//						cerr << i << " " << j << " " << k << " " << m << " ";
//						debug(lst);
						f[i&1][j][k][m][lst]=0;
						for ( int mp = lst ; mp <= m ; mp++ )
							for ( int Lst = 1 ; Lst <= j+k-lst ; Lst++ )
							{
//								if(i==3&&j==2&&k==2&&m==4&&lst==1)
//								{
//									printf("add f[%d][%d][%d][%d][%d]\n",2,j-lst,k,m-mp,Lst);
//									printf("=%d\n",f[0][j-lst][k][m-mp][Lst]);
//								}
								if(i&1)f[1][j][k][m][lst]+=f[0][j-lst][k][m-mp][Lst]*g[lst][Lst][mp]%mod;
								else f[0][j][k][m][lst]+=f[1][j][k-lst][m-mp][Lst]*g[lst][Lst][mp]%mod;
							}
						f[i&1][j][k][m][lst]%=mod;
						f[i&1][j][k][m][lst]*=C(n-j-k+lst,lst);
						f[i&1][j][k][m][lst]%=mod;
						if(j==n/2&&k==n/2)ans[m]+=f[i&1][j][k][m][lst];
//						printf("f[%d][%d][%d][%d][%d]=%d\n",i,j,k,m,lst,f[i&1][j][k][m][lst]);
					}
	}
	for ( int m = n-1 ; m <= n*(n-1)/2 ; m++ )
	{
		cout << ans[m]%mod << " ";
//		int ans=0;
//		int i=1,j=n/2,k=n/2;
//		for ( int lst = 0 ; lst <= n ; lst++ )
//			ans+=f[i][j][k][m][lst];
//		cout << ans%mod << " ";
	}
	return 0;
}
//10 998244353
//4 998244353
//2 998244353
2025/1/21 16:22
加载中...