[ZROI CSP七连测Day1] 华二 题解
__vector__ · · 个人记录
做法
分类讨论。
经简单计算得知,
剩下的数
再剩下的数
所以,本题的做法:
- 先忽略
1,5,7 的存在,并用6 将数列分成一些段。 - 对于每一段,设
x,y 分别代表第一,二类的元素数量,由于每一类的内部相对位置是固定的,所以答案就是在总共x+y 个元素中选出x 个元素作为第一类元素的位置(当然换成选y 个作为第二类元素的位置也是可以的),答案就是C_{x+y}^x 。 - 求出每一段的答案后,拼起来。
- 然后考虑将
1,5,7 插入的方案数,直接算就行,这个答案就很显然了。
Code
#include <bits/stdc++.h>
using namespace std;
namespace Main
{
typedef long long ll;
const ll mod=998244353;
const int maxn=1e5+5;
inline int read()
{
int x=0;
char ch=getchar();
while(isdigit(ch))
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x;
}
int n;
int a[maxn];
int _c1,_c5,_c7;
int _cla1,_cla2;
ll fact[maxn];
ll ksm(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1)ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
ll inv(ll a)
{
return ksm(a,mod-2);
}
inline ll C(int n,int m)
{
if(m>n)return 0;
return fact[n]*inv(fact[m])%mod*inv(fact[n-m])%mod;
}
void main()
{
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
_c1+=(a[i]==1);
_c5+=(a[i]==5);
_c7+=(a[i]==7);
}
fact[0]=1;
for(int i=1;i<=n;i++)
{
fact[i]=fact[i-1]*i%mod;
}
int l=1;
ll ans=1;
for(int i=1;i<=n;i++)
{
if(a[i]==2||a[i]==4||a[i]==8)_cla1++;
if(a[i]==3||a[i]==9)_cla2++;
if(a[i]==6)
{
ans*=C(_cla1+_cla2,_cla1);
ans%=mod;
_cla1=_cla2=0;
}
}
if(_cla1||_cla2)
{
ans*=C(_cla1+_cla2,_cla1);
ans%=mod;
}
ans=ans*C(n,_c1)%mod*C(n-_c1,_c5)%mod*C(n-_c1-_c5,_c7)%mod;
printf("%lld",ans);
}
}
int main()
{
Main::main();
return 0;
}