题意
给定一个整数n,k,输入n个正整数a(0=<a<=2),求对于从i1=1开始向内层循环从i2=i1+1,i3=i2+1....ik=ik-1+1连续相乘的值,对结果取模,
思路
从这道题很容易看出给定a为0,1,2,对于a=0的情况与其他相乘仍为0,没有贡献,对于1的情况他不会使答案增加,只有对于2的情况能使答案增加。于是我们只需要算出n个数中有多少个1,多少个2,设num1为1的个数,num2为2的个数,于是答案为从num2中取i个2*num1中取k-i个1*2^i;
而对于组合数我们需要用逆元来解。这道题还应注意用sacnf,printf.才不会超时。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll ksm(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
int main(){
ll n,k,f[10000010],num2=0,num1=0,a;
scanf("%lld%lld",&n,&k);
f[0]=1;//pow2[0]=1;
for(int i=1;i<=n;i++){
scanf("%lld",&a);
if(a==1)num1++;
if(a==2)num2++;
f[i]=(f[i-1]*i)%mod;
//pow2[i]=(pow2[i-1]*2)%mod;
}
ll ans=0;
for(int i=0;i<=k;i++){
if(num2>=i&&num1>=k-i){
ll niyuan2=ksm((f[num2-i]*f[i])%mod,mod-2);
ll niyuan1=ksm((f[num1-k+i]*f[k-i])%mod,mod-2);
ans=(ans+(f[num2]*niyuan2%mod)*(f[num1]*niyuan1%mod)%mod*ksm(2,i)%mod)%mod;
}
}
printf("%lld",ans);
}