ARC175A 题解
题意
在一个环上有
给定
思路
如果把这个环画出来,环上就是一个人一个勺子交叉,如此重复
模拟一下就会发现,若某两人选择勺子的方向不同,则他们之间剩下的勺子数与人数之和为奇数,这样一定不合法。
所以我们得到,合法的取法只有两种,即所有人都取自己左手边的勺子,或所有人都取自己右手边的勺子。
那么只需要模拟取两次,每次都直接钦定每个人所拿的勺子,再按
处理时,若不拿的另一把勺子还在,就必须确定惯用手以拿到指定的那把,此时若与
此处不需要考虑自己要拿的勺子是否已被取走,因为每个人都只会取自己对应的那把勺子,不会出现拿别人勺子的情况。
最后把两种取法对应的方案数相加即可。
代码
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N=2e5+10;
const int mod=998244353;
int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') w=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar();}
return s*w;
}
int n,sa=1,sb=1,p[N];
char s[N];
bool v[N];//勺子是否被取走
signed main()
{
n=read();
for(int i=1;i<=n;i++) p[i]=read();
cin>>s;
for(int i=1;i<=n;i++)//所有人都取左手边的
{
if(v[(p[i]%n)+1]) //若另一把已被取走,则惯用手任意
{
if(s[p[i]-1]=='?') sa=(sa*2)%mod;//若是问号则乘2
}
else if(s[p[i]-1]=='R') //另一把未被取走,则需确定惯用手
{
sa=0;
break;
}//此时若与给定信息冲突则无解
v[p[i]]=1;//标记已取走
}
memset(v,0,sizeof(v));
for(int i=1;i<=n;i++)//都取右手边的,同上
{
if(v[p[i]])
{
if(s[p[i]-1]=='?') sb=(sb*2)%mod;
}
else if(s[p[i]-1]=='L')
{
sb=0;
break;
}
v[(p[i]%n)+1]=1;
}
cout<<(sa+sb)%mod;
return 0;
}