卡常#10,求调
查看原帖
卡常#10,求调
788951
TLE_AK楼主2024/9/7 01:49
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace acac
{	
	const int mod=998244353;

	struct node
	{
		int f[10][10];
		void clear()
		{
			for(int i=0;i<=2;i++)
			{
				for(int j=0;j<=2;j++)
				{
					f[i][j]=-1;
				}	
			}
		}
		void wr()
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					cout<<f[i][j]<<' ';
				}
				cout<<endl;
			}
		}
		//剩余i个(x,x-1),剩余j个x 
	};
	
	node zy(node a,int sum)
	{
		node b;
		b.clear();
		for(int i=0;i<=2;i++)
		{
			for(int j=0;j<=2;j++)
			{
				if(a.f[i][j]==-1)continue;
				int sy=sum-i-j;
				for(int k=0;i+j+k<=sum&&k<3;k++)
				{
					b.f[j][k]=max(b.f[j][k],min(4ll,a.f[i][j]+i+sy/3));
					sy--;
				}
			}	
		}
		return b;	
	} 
	
	bool cheak(node a)
	{
		for(int i=0;i<3;i++)
		{
			for(int j=0;j<3;j++)
			{
				if(a.f[i][j]>=4)return 1;
			}
		}
		return 0;
	}
	
	void gmax(node &a,node b)
	{
		for(int i=0;i<3;i++)
		{
			for(int j=0;j<3;j++)
			{
				a.f[i][j]=max(a.f[i][j],b.f[i][j]);
			}
		}
	}

	struct hpam
	{
		node a[4];
		int dz;	
		void clear()
		{
			dz=0;
			a[0].clear();
			a[1].clear(); 
		}
		void wr()
		{
			a[0].wr();
			cout<<endl;
			a[1].wr();
			cout<<endl;
		}
	}D[10010];
	
	bool operator < (hpam a,hpam b)
	{
		for(int k=0;k<2;k++)
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					if(a.a[k].f[i][j]!=b.a[k].f[i][j])return a.a[k].f[i][j]<b.a[k].f[i][j];
				}
			}
		}
		return a.dz<b.dz;
	}
	
	hpam update(hpam a,int sum)
	{
		if(a.dz==1e9)return a;
		hpam ans;
		ans.clear();
		ans.dz=a.dz+(sum>=2);
		gmax(ans.a[0],zy(a.a[0],sum));
		gmax(ans.a[1],zy(a.a[1],sum));
		if(sum>=2)
		{
			for(int i=0;i<3;i++)
			{
				for(int j=0;j<3;j++)
				{
					gmax(ans.a[1],zy(a.a[0],sum-2));
				}
			}
		}
		if(cheak(ans.a[1])||ans.dz==7)
		{
			ans.clear();
			ans.dz=1e9;
		}
		return ans;
	}
	
	int e[3010][5];
	map<hpam,int>mp; 
	int tot,ww;
	void bfs()
	{
		int l=1,r=0;
		hpam st;
		st.clear();
		st.a[0].f[0][0]=0;
		D[++r]=st;
		while(l<=r)
		{
			hpam u=D[l++];
			for(int i=0;i<=4;i++)
			{
				hpam v=update(u,i);
			//	v.wr();
				if(!mp[v])
				{
					mp[v]=++tot;
					e[mp[u]][i]=tot;
					if(v.dz!=1e9)D[++r]=v;
					else ww=tot;
				}
				else e[mp[u]][i]=mp[v];
			}
		}
	}
	
	int jc[410],jcn[410];
	int ksm(int a,int k)
	{
		int ans=1,bs=a;
		while(k)
		{
			if(k&1)ans=ans*bs%mod;
			bs=bs*bs%mod;
			k>>=1;
		}
		return ans;
	}
	void init(int n)
	{
		jc[0]=jc[1]=1;
		for(int i=1;i<=n;i++)
		{
			jc[i]=jc[i-1]*i%mod;
		}
		jcn[n]=ksm(jc[n],mod-2);
	//	cout<<jcn[n]<<' ';
		jcn[0]=1;
		for(int i=n-1;i;i--)
		{
			jcn[i]=jcn[i+1]*(i+1)%mod;
	//		cout<<jcn[i]<<' ';
		}
	} 
	
	int C(int x,int y)
	{
		if(x<y)return 0;
		return jc[x]*jcn[y]%mod*jcn[x-y]%mod;
	}

	int T[410],dp[2][410][3010];

	int read()
	{
		char ch=getchar();
		while(ch<'0'||ch>'9')
		{
			ch=getchar();	
		}	
		int ans=0;
		while(ch>='0'&&ch<='9')
		{
			ans=ans*10+ch-'0';
			ch=getchar();
		}
		return ans;
	} 

	int main()
	{
		int n=read();
	//	scanf("%lld",&n);
		for(int i=1;i<=13;i++)
		{
			int a,b;
			a=read(),b=read();
			T[a]++;
		}
		init(4*n);
		bfs();
		//cout<<tot<<endl;
		int now=1,pre=0;
		dp[0][0][1]=1;
		for(int i=1;i<=n;i++)
		{
			memset(dp[now],0,sizeof(dp[now]));
			for(int j=1;j<=tot;j++)
			{
				for(int k=0;k<=4*(i-1);k++)
				{
					for(int a=0;a+T[i]<=4;a++)
					{
						dp[now][k+a][e[j][a+T[i]]]+=dp[pre][k][j]*C(4-T[i],a)%mod;
						dp[now][k+a][e[j][a+T[i]]]%=mod;
					
					}
				}
			}
			swap(now,pre);
		}
		int ans=0;
		for(int i=0;i<=n*4-13;i++)
		{
			for(int j=1;j<=tot;j++)
			{
				if(j==ww)continue;
				ans+=ksm(C(4*n-13,i),mod-2)*dp[pre][i][j]%mod;
				ans%=mod;
		//		cout<<dp[pre][i][j]<<' ';
			}
		//	cout<<endl;
		}
		cout<<ans;
		return 0;
	}
}
#undef int
int main()
{
	acac::main();
	return 0;
}
/*
7
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2
6 1
6 2
7 1
*/

总感觉可能是哪里实现错了,#8不开快读卡不过去

2024/9/7 01:49
加载中...