1546 #732 (Div. 2) D. AquaMoon and Chess(组合数,规律)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1546 #732 (Div. 2) D. AquaMoon and Chess(组合数,规律)相关的知识,希望对你有一定的参考价值。

LINK

考虑序列中一定是一段 0 0 0,然后一段 1 1 1,然后一段 0 0 0

考虑单独拿出一段 1 1 1来观察它的移动

00111100 00111100 00111100

可以发现,一开始只能从第二个 1 1 1或者倒数第 2 2 2 1 1 1往外面置换,于是可以得到

01101100 01101100 01101100或者 00110110 00110110 00110110

如果你想,现在你可以让 11 11 11以任意的方式排列

不为什么!!只因为它们是 11 11 11的形式,和 0 0 0置换后还是 11 11 11,所以可以一直往左或往右

然而当这段 1 1 1为奇数时,会留下一个 1 1 1,这个 1 1 1是不成组的,无法自由移动

最后这个单独的 1 1 1的位置取决于其他成组 11 11 11的移动

所以设序列中有 x x x 11 11 11, y y y 0 0 0

相当于 x + y x+y x+y个元素,其中 x x x个是 11 11 11,任意排列( 1 1 1是无所谓的, 11 11 11的排列决定了剩余 1 1 1的位置)

答案是 ( x + y x ) \\binom{x+y}{x} (xx+y)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int maxn = 3e5+10;
int n,f[109][109],fac[maxn];
char a[maxn];
int quick(int x,int n)
{
	int ans = 1;
	for( ; n ; n>>=1,x=x*x%mod )
		if( n&1 )	ans = ans*x%mod;
	return ans;
}
int C(int n,int m)
{
	if( m>n )	return 0ll;
	return fac[n]*quick( fac[m]*fac[n-m]%mod,mod-2 )%mod;
}
signed main()
{
	fac[0] = 1;
	for(int i=1;i<=200000;i++)	fac[i] = 1ll*fac[i-1]*i%mod;
	int t; cin >> t;
	while( t-- )
	{
		cin >> n >> ( a+1 );
		int x = 0, y = 0, zi = 0;
		a[n+1] = '0';
		for(int i=1;i<=n;i++)
		{
			if( a[i]=='1' )	zi++;
			else	
			{
				y++; x += zi/2;
				zi = 0;
			}
		}
		x += zi/2;
		cout << C( x+y,x ) << endl;
	}
}

以上是关于1546 #732 (Div. 2) D. AquaMoon and Chess(组合数,规律)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #732 (Div. 2) D. AquaMoon and Chess

Codeforces Round #732 (Div. 2) D. AquaMoon and Chess

Codeforces Round #732 (Div. 1&&Div. 2)

Codeforces Round #732 (Div. 1&&Div. 2)

Codeforces Round #732 (Div. 1&&Div. 2)

Codeforces Round #732 div.2 A-E题解