思路:找约数那里记得要包括1跟它本身。
因为模数不是质数,而且很大,所以分解成几个质数,然后对n的约数对每一个质数分别求方案数的和,最后再用中国剩余定理求出数字就可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod = 998244353;
typedef long long ll;
const ll maxn = 1e6+10;
ll Jc[maxn];
void calJc() //求maxn以内的数的阶乘
{
Jc[0] = Jc[1] = 1;
for(ll i = 2; i < maxn; i++)
Jc[i] = Jc[i - 1] * i % mod;
}
ll pow(ll a, ll n, ll mod) //快速幂 a^n % p
{
ll ans = 1;
while(n)
{
if(n & 1) ans = ans * a % mod;
a = a * a % mod;
n >>= 1;
}
return ans;
}
ll niYuan(ll a) //费马小定理求逆元
{
return pow(a, mod - 2, mod);
}
ll C(ll n, ll r) //计算C(n, r)
{
if(r>n)return 0;
return Jc[n] * niYuan(Jc[r]) % mod
* niYuan(Jc[n - r]) % mod;
}
int main()
{
int t;
scanf("%d", &t);
calJc();
while(t--)
{
int n;
char ch[1000000];
scanf("%d%s", &n, ch);
int one = 0, zero = 0;
for(int i = 0;i<n;i++)
{
if(ch[i] == '0') zero++;
else if(ch[i] == '1' && ch[i+1] == '1')
{
one++;
i++;
}
}
ll ans = 1ll* C(zero+one,zero) %mod;
cout<<ans<<endl;
}
return 0;
}