萌新求助如何卡常
  • 板块P8366 [LNOI2022] 题
  • 楼主yummyeaten
  • 当前回复16
  • 已保存回复16
  • 发布时间2024/11/28 00:24
  • 上次更新2024/11/28 12:36:35
查看原帖
萌新求助如何卡常
101694
yummyeaten楼主2024/11/28 00:24

写了一个多小时,终于勉强通过,但是为什么别人 130130 毫秒就能跑完啊 /ll

#include<bits/stdc++.h>
using namespace std;
const int Mod=1'000'000'007;
int CTest,n,cnt[2][20][20][20][20][20][20];
char s[65];
#define BeginLoop for(int c1=0;c1<=n;c1++){\
int rest1=n-c1;\
for(int c2=0;c2<=rest1;c2++){\
	int rest2=rest1-c2;\
	for(int c3=0;c3<=rest2;c3++){\
		int rest3=rest2-c3;\
		for(int c32=0;c32<=rest3;c32++){\
			int rest4=rest3-c32;\
			for(int c21=0;c21<=rest4;c21++){\
				for(int c13=0;c13+c21<=rest4;c13++){

#define EndLoop }}}}}}

int main(){
	for(scanf("%d",&CTest);CTest;CTest--){
		memset(cnt,0,sizeof cnt);
		scanf("%d%s",&n,s+1);
		cnt[0][0][0][0][0][0][0]=1;
		for(int i=1;i<=n*3;i++){
			int C=i&1,R=C^1;
			if(s[i]=='0'){
				BeginLoop
				long long tmp=0;
				if(c1>0) tmp+=cnt[R][c1-1][c2][c3][c32][c21][c13];
				if(c21>0 && c2<n)tmp+=cnt[R][c1][c2+1][c3][c32][c21-1][c13]*(c2+1ll);
				if(c32<n)tmp+=cnt[R][c1][c2][c3][c32+1][c21][c13]*(c32+1ll);
				if(c2>0) tmp+=cnt[R][c1][c2-1][c3][c32][c21][c13];
				if(c32>0 && c3<n)tmp+=cnt[R][c1][c2][c3+1][c32-1][c21][c13]*(c3+1ll);
				if(c13<n)tmp+=cnt[R][c1][c2][c3][c32][c21][c13+1]*(c13+1ll);
				if(c3>0) tmp+=cnt[R][c1][c2][c3-1][c32][c21][c13];
				if(c13>0 && c1<n)tmp+=cnt[R][c1+1][c2][c3][c32][c21][c13-1]*(c1+1ll);
				if(c21<n)tmp+=cnt[R][c1][c2][c3][c32][c21+1][c13]*(c21+1ll);
				cnt[C][c1][c2][c3][c32][c21][c13]=tmp%Mod;
				EndLoop
			}
			else if(s[i]=='1'){
				BeginLoop
					long long tmp=0;
					if(c1>0) tmp+=cnt[R][c1-1][c2][c3][c32][c21][c13];
					if(c21>0 && c2<n)tmp+=cnt[R][c1][c2+1][c3][c32][c21-1][c13]*(c2+1ll);
					if(c32<n)tmp+=cnt[R][c1][c2][c3][c32+1][c21][c13]*(c32+1ll);
					cnt[C][c1][c2][c3][c32][c21][c13]=tmp%Mod;
				EndLoop
			}
			else if(s[i]=='2'){
				BeginLoop
					long long tmp=0;
					if(c2>0) tmp+=cnt[R][c1][c2-1][c3][c32][c21][c13];
					if(c32>0 && c3<n)tmp+=cnt[R][c1][c2][c3+1][c32-1][c21][c13]*(c3+1ll);
					if(c13<n)tmp+=cnt[R][c1][c2][c3][c32][c21][c13+1]*(c13+1ll);
					cnt[C][c1][c2][c3][c32][c21][c13]=tmp%Mod;
				EndLoop
			}
			else if(s[i]=='3'){
				BeginLoop
					long long tmp=0;
					if(c3>0) tmp+=cnt[R][c1][c2][c3-1][c32][c21][c13];
					if(c13>0 && c1<n)tmp+=cnt[R][c1+1][c2][c3][c32][c21][c13-1]*(c1+1ll);
					if(c21<n)tmp+=cnt[R][c1][c2][c3][c32][c21+1][c13]*(c21+1ll);
					cnt[C][c1][c2][c3][c32][c21][c13]=tmp%Mod;
				EndLoop
			}
		}
		long long res=cnt[n%2][0][0][0][0][0][0];
		for(int i=2;i<=n;i++)
			res=res*i%Mod;
		printf("%lld\n",res);
	}
	return 0;
}
2024/11/28 00:24
加载中...