首页 > 其他分享 >CF1545B题解

CF1545B题解

时间:2023-08-17 11:57:51浏览次数:27  
标签:落单 num2 int 题解 棋子 CF1545B base

CF1545B题解

题目描述

你有一个长为 \(n\) 的棋盘,这个棋盘上有一些棋子,你可以进行如下操作:

如果第 \(i + 2\) 个位置是空的,且第 \(i + 1\) 个位置非空,则可以将第 \(i\) 个位置的棋子挪到第 \(i + 2\) 个位置 (\(i + 2 \leq n\)).

如果第 \(i - 2\) 个位置是空的,且第 \(i - 1\) 个位置非空,则可以将第 \(i\) 个位置的棋子挪到第 \(i - 2\) 个位置 (\(i - 2 \geq 1\)).

现在将给出一个棋盘的初始状态,求可以通过上述操作可以到达的状态数,你可以进行任意次操作,答案对 \(998244353\) 取模.

题解

模拟样例,很容易发现棋子是两两一组进行移动的。我们考虑在没有落单的棋子时我们怎么做这道题,显然我们可以用组合数学插板法解决。

接着,我们来考虑落单的棋子,我们观察发现,落单棋子,要么不动,要么被推着走,所以,成对棋子的移动,完全决定了落单棋子的移动,我们直接删除他们即可。

我们设空格的数量为 \(num1\),成对棋子的对数为 \(num2\)。答案即为 \(C(num1+num2,num2)\)。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
const int N=2e5+100;
int t,n,inv[N],qinv[N],qz[N];
string s;
int qpow(int a,int b)
{
	int s=1,base=a;
	while(b!=0)
	{
		if(b&1==1)
		{
			s*=base;
			s%=mod;
		}
		base*=base;
		base%=mod;
		b>>=1;
	}
	return s;
}
void pre()
{
	for(int i=1;i<=N-100;i++)
	{
		inv[i]=qpow(i,mod-2);
	}
	qinv[0]=1;
	for(int i=1;i<=N-100;i++)
	{
		qinv[i]=qinv[i-1]*inv[i];
		qinv[i]%=mod; 
	}
	qz[0]=1;
	for(int i=1;i<=N-100;i++)
	{
		qz[i]=qz[i-1]*i;
		qz[i]%=mod;
	}
	return;
}
void C(int a,int b)
{
	cout<<((qz[a]*qinv[a-b])%mod*qinv[b])%mod<<endl;
	return;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	pre();
	cin>>t;
	while(t--)
	{
		cin>>n>>s;
		s=" "+s;
		int num1=0,num2=0;
		bool f=1;
		for(int i=1;i<=n;i++)
		{
			if(s[i]=='0')
			{
				f=1;
				num1++;	
			}
			else
			{
				f^=1;
				num2+=f;
			}
		}
		C(num1+num2,num2);
	}
	return 0;
}

标签:落单,num2,int,题解,棋子,CF1545B,base
From: https://www.cnblogs.com/ddream123/p/17637217.html

相关文章

  • arc136,arc137,arc138题解
    ARC136A-EAA↔BB贪心。可以把BB换成A,可以把BA换成AB。BTripleShift直观上觉得只要数集相同,那么就是可以变换的。大概方法就是每次找到正确的数把它挪到数列的端点,这样显然是可行的。但是在相反的三个上出现了问题,原因在于只剩最后两个数时方向可能是反着的。分析......
  • arc133,arc134,arc135题解
    ARC133A-EAErasebyValue扣掉一个数当且仅当这个数后面有更小的数。特判单增即可。BDividingSubsequence相对比较有启发性。发现有倍数关系的数对只有\(O(n\logn)\)对,于是可以把对应下标攒成一堆二元组,于是一个合法的取数方案就变成了两个维度分别严格上升的元素集合......
  • arc130,arc131,arc132题解
    ARC130A-DARemoveOneCharacter对每个连续块分别处理即可。BColorfulLines非常经典的题目,对于每一行每一列记录最后出现的颜色并计算贡献即可。CDigitSumMinimization有点细节。枚举最后两个数,显然加起来超过十是很好的;然后前面的数应该尽量凑九,然后要注意尽量不选......
  • FJOI2018 领导集团问题 题解
    先考虑暴力dp。设\(f_{u,x}\)表示在子树\(u\)中选出的节点集合的\(w\)最小值为\(x\)的情况下,最大的节点集合的大小。有两种转移(选不选\(u\)):\(f_{u,x}\gets\sum\limits_{v\in\text{substree}_u}f_{v,\gex}\)\(f_{u,w_u}\gets\sum\limits_{v\in\text{substree}_u}......
  • [CF1730D] Prefixes and Suffixes 题解
    首先发现后缀和前缀比较不好看,所以翻转第二个字符串,记为\(T'\)。这样就变成了操作两个字符串的前缀。观察发现,操作\(k\)等价于交换\(S[1\simk]\)和\(T'[1\simk]\),然后翻转\(S[1\simk]\)和\(T'[1\simk]\)。结论1:同一个下标上的字符对恒定。因为我们所有的操作都......
  • CF932E Team Work 题解
    Description给定\(n,k\),求:\[\displaystyle\sum_{i=1}^{n}{\binom{n}{i}\timesi^k}\]\(1\leqk\leq5000,1\leqn\leq10^9\)。Solution看到那个\(i^k\)很不爽,但是\(k\)很小,考虑用斯特林数改写一下:\[i^k=\sum_{j=0}^{k}{\binom{i}{j}\left\{{\begin{matrix}k......
  • P1110题解
    首先我们考虑第一种情况怎么处理,显然我们可以给原数列的每个数开一个\(vector\),每加一个数丢到对应的\(vector\)后面就行了。再看第二个操作,你考虑新加一个数会有什么影响。原来的两个\(vector\)是这样的:新加一个数进去以后:原来的\(|y-x|\)要删除,新增了\(|x-z|\)和\(|z-y|\)......
  • 【题解】[ARC158C] All Pair Digit Sums
    传送门题目分析我们可以先从简单一点的情况开始分析,如果现在\(a_{[i]},a_{[j]}\)都不会进位,那么最后的\(f(a_{[i]}+a_{[j]})=f(a_{[i]})+f(a_{[j]})\)。证明如下:有两个数\(x=\overline{x_nx_{n-1}....x_1}\)和\(y=\overline{y_my_{m-1}...y_1}\)。令\(n\lem\),由于不会......
  • vscode git突然失效问题解决
    一:首先配置‘环境变量’打开电脑‘设置’----->关于--->高级系统设置---->环境变量------>用户和系统变量都设置一下,点击Path------->新建-------->将git-bash的应用程序地址粘贴到里面----->一直点击确定,直到退出(这里的应用程序地址看自己保存的bash.exe的位置)我的是:C:\Program......
  • 新生赛题解
    A题解:不会#include<bits/stdc++.h>#pragmaGCCoptimize("Ofast")#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<cmath>//#definedoublelongdoub......