題目大意
給定
題目分析
又是一道好題。
在範老師@AwD的博客看懂的,大家可以過去膜拜一下。
思路是這樣的:令
那麼答案就是
這個看起來不太好算,我們對後面的部分容斥一下,變成
其實就是
這個怎麼計算呢?令
顯然必須要滿足
轉移的話,假設第
初始狀態
時間複雜度
代碼實現
#include <iostream>
#include <cctype>
#include <cstdio>
using namespace std;
int read()
{
int x=0,f=1;
char ch=getchar();
while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();
while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int P=1000000007;
const int N=1005;
const int S=1024;
int f[2][S][S];
int a[N];
int n;
void update(int &x,int y){x=(x+y)%P;}
int dp()
{
f[0][S-1][S-1]=1;
for (int i=0;i<n;++i)
{
int cur=i&1,nxt=cur^1,x=a[i+1];
for (int j=0;j<S;++j)
{
for (int k=j;k;k=(k-1)&j) f[nxt][k][j]=0;
f[nxt][0][j]=0;
}
for (int j=0;j<S;++j)
{
for (int k=j;k;k=(k-1)&j) update(f[nxt][k][j],f[cur][k][j]),update(f[nxt][k&x][j&x],f[cur][k][j]),update(f[nxt][k&x][k|j&x],P-f[cur][k][j]);
update(f[nxt][0][j],f[cur][0][j]);
}
}
return f[n&1][0][0];
}
int main()
{
freopen("never.in","r",stdin),freopen("never.out","w",stdout);
n=read();
for (int i=1;i<=n;++i) a[i]=read();
printf("%d\n",dp());
fclose(stdin),fclose(stdout);
return 0;
}