题目链接
题目思路
设\(dp[i][sta][con][sum][flag]\)
表示在第\(i\)个位置,前\(7\)位的状态为\(sta\),\(con\)为第\(8\)位后连续的\(1\)的奇偶性,\(sum\)为第\(8\)位后\(1\)的个数的奇偶性
然后大力转移
主要是没想到要枚举前\(7\)位的状态,看到\(a\)数组第只有100的时候应该要想想
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod= 998244353;
const double eps=1e-6;
int m;
ll l;
int a[maxn];
int num[100],cnt;
ll dp[65][(1<<7)+5][2][2][2];
bool check(int sta,int con,int sum){
for(int i=0;i<m;i++){
int now=sta+i;
int cnt=0;
for(int j=0;j<=7;j++){
if((now>>j)&1) cnt++;
}
cnt+=sum;
if(now>=(1<<8)){
if(con%2==0) cnt++;// 改变奇偶
}
if(cnt%2!=a[i]){
return 0;
}
if(i==m-1){
return 1;
}
}
return 1;
}
ll dfs(int pos,int sta,int con,int sum,bool flag){
if(pos==-1){
return check(sta,con,sum);
}
if(!flag&&dp[pos][sta][con][sum][flag]!=-1){
return dp[pos][sta][con][sum][flag];
}
int lim=(flag?num[pos]:1);
ll ans=0;
for(int i=0;i<=lim;i++){
if(pos<=7){
if(i==0){
ans+=dfs(pos-1,sta,con,sum,flag&&num[pos]==i);
}else{
ans+=dfs(pos-1,sta+(1<<pos),con,sum,flag&&num[pos]==i);
}
}else{
if(i==0){
ans+=dfs(pos-1,sta,0,sum,flag&&num[pos]==i);
}else{
ans+=dfs(pos-1,sta,(con+1)%2,(sum+1)%2,flag&&num[pos]==i);
}
}
}
return dp[pos][sta][con][sum][flag]=ans;
}
void solve(ll x){
cnt=0;
while(x){
num[cnt++]=x%2;
x/=2;
}
memset(dp,-1,sizeof(dp));
ll ans=dfs(cnt-1,0,0,0,1);
printf("%lld\n",ans);
}
signed main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d%lld",&m,&l);
for(int i=0;i<m;i++){
scanf("%d",&a[i]);
}
solve(l);
}
return 0;
}