显然只有2的幂次对产生2048有用,即
20,21,22....211
f[i][j]表示前i个2的幂次,合并了j个
2i
的子序列数
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void read(int &x)
{
char c; while(!((c=getchar())>='0'&&c<='9'));
x=c-'0';
while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 110000;
const int Mod = 998244353;
inline void add(int &a,int b){a+=b;if(a>=Mod)a-=Mod;}
int pw(int x,int k)
{
int re=1;
for(;k;k>>=1,x=(ll)x*x%Mod) if(k&1)
re=(ll)re*x%Mod;
return re;
}
int s[maxn],ps[maxn];
void pre()
{
s[0]=1; for(int i=1;i<maxn;i++) s[i]=(ll)s[i-1]*i%Mod;
ps[maxn-1]=pw(s[maxn-1],Mod-2);
for(int i=maxn-2;i>=0;i--) ps[i]=(ll)ps[i+1]*(i+1)%Mod;
}
int C(const int n,const int m){return (ll)s[n]*ps[m]%Mod*ps[n-m]%Mod;}
int n;
int f[20][2048],suf[maxn];
int To[maxn];
int num[20];
int ans,ti;
int main()
{
pre();
for(int i=0;i<=11;i++) To[1<<i]=i+1;
while(scanf("%d",&n)!=EOF&&n)
{
memset(num,0,sizeof num);
memset(f,0,sizeof f);
for(int i=1;i<=n;i++)
{
int x; read(x);
num[To[x]]++;
}
ans=0;
f[0][0]=pw(2,num[0]);
int now=num[0];
for(int i=1;i<=12;i++)
{
now+=num[i];
int y=2048>>i-1;
suf[num[i]+1]=0;
for(int j=num[i];j>=0;j--)
{
suf[j]=suf[j+1];
add(suf[j],(ll)C(num[i],j)*pw(2,n-now)%Mod);
}
for(int j=0;j<2048;j++) if(f[i-1][j])
{
int tmp=f[i-1][j];
int x=j>>1,u=min(y-x-1,num[i]);
for(int k=0;k<=u;k++)
add(f[i][x+k],(ll)tmp*C(num[i],k)%Mod);
add(ans,(ll)tmp*suf[u+1]%Mod);
}
}
printf("Case #%d: %d\n",++ti,ans);
}
return 0;
}