代码如下:
#include <bits/stdc++.h>
using namespace std;
namespace yhy{
#define ll long long
const ll Mod=998244353;
ll f[65][17][1025];
ll n;
int m;
ll a[11];
ll C[11][11];
ll ksm(ll a,int b) {
ll rt=1ll;
while(b) {
if(b&1) rt=rt*a%Mod;
a=a*a%Mod;
b>>=1;
}
return rt;
}
ll Get_C(ll n,int m) {
ll rt=1;
for(int i=0;i<m;i++) rt=rt*((n-i)%Mod)%Mod*ksm(m-i,Mod-2)%Mod;
return rt;
}
ll Solve() {
ll rt=0;
ll opt,sum;
bool flag;
for(int i=0;i<(1<<m);i++) {
opt=flag=1;
sum=0;
for(int j=1;j<=m;j++) {
if((i>>(j-1))&1) {
opt=-opt;
sum+=a[j]+1;
if(sum>n) {
flag=0;
break;
}
}
}
if(flag==0) continue;
rt=(rt+opt*Get_C(n-sum+m-1,m-1))%Mod;
}
return rt;
}
ll dfs(int u,int add,int Num) {
if(u==60) {
return (add==0) && (Num==0);
}
if(f[u][add][Num]!=-1) {
return f[u][add][Num];
}
ll rt=0;
int Now_add=0;
int all=0;
int flag=1;
for(int i=Num;;i=(i-1)&Num) {
flag=1;
for(int j=1;j<=m;j++) {
if(((Num>>(j-1))&1) && (!((i>>(j-1))&1))) {
if(!((a[j]>>u)&1)) {
flag=0;
break;
}
}
}
if(flag==0) {
if(i!=0) continue;
else break;
}
Now_add=0;
all=0;
for(int j=1;j<=m;j++) {
if((Num>>(j-1))&1) {
if((i>>(j-1))&1) {
all++;
}
}
else {
Now_add+=(a[j]>>u)&1;
}
}
if(((Now_add+add)&1)!=((n>>u)&1)) {
if(all==0 || !(Now_add&1)) {
if(i==0) break;
else continue;
}
for(int k=1;k<=all;k+=2) {
rt+=C[all][k]*dfs(u+1,(Now_add+add+k)>>1,i);
rt%=Mod;
}
}
else {
if(Now_add&1) {
if(i==0) break;
else continue;
}
for(int k=0;k<=all;k+=2) {
rt+=C[all][k]*dfs(u+1,(Now_add+add+k)>>1,i);
rt%=Mod;
}
}
if(i==0) break;
}
return f[u][add][Num]=rt;
}
int main() {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=0;i<=59;i++) {
for(int j=0;j<=m;j++) {
for(int k=0;k<(1<<m);k++) {
f[i][j][k]=-1;
}
}
}
C[0][0]=C[1][0]=C[1][1]=1;
for(int i=2;i<=m;i++) {
C[i][0]=1;
for(int j=1;j<=i;j++) {
C[i][j]=(C[i-1][j-1]+C[i-1][j])%Mod;
}
}
for(int i=1;i<=m;i++) cin>>a[i];
ll ans=Solve();
for(int i=0;i<(1<<m);i++) {
ans-=dfs(0,0,i);
ans%=Mod;
}
ans=(ans+Mod)%Mod;
cout<<ans<<'\n';
return 0;
}
}
int main() {
yhy::main();
return 0;
}