解法
若把序列分为两部分,设总的异或和为
s
s
s,其中一部分的异或和为
x
x
x,那么另一部分就为
s
⊕
x
s\oplus x
s⊕x
x
≥
x
⊕
s
x\ge x\oplus s
x≥x⊕s的充要条件为
h
i
g
h
b
i
t
(
s
)
&
x
≠
0
highbit(s)\&x\ne0
highbit(s)&x=0
然后优化区间DP的转移即可
code
#include<iostream>
#define ll long long
using namespace std;
const int N = 1e4+5;
int n;
int c[N], tot;
ll L[N], R[N],a[N],pre[N];
bool dp[N][N];
ll rebuild(ll x){
tot=0;
while(x){
c[++tot]=x&1;
x>>=1;
}
while(tot<=60) c[++tot]=0;
x=0;
for(int i=1;i<=tot;++i) x+=(ll)c[tot-i+1]<<(i-1);
return x;
}
ll lowbit(ll x){return x & -x;}
void solve(){
scanf("%d",&n); ll v;
for(int i=1;i<=n;++i) L[i]=R[i]=0;
for(int i=1;i<=n;++i) cin >> a[i], a[i]=rebuild(a[i]), pre[i]=pre[i-1]^a[i];
for(int i=1;i<=n;++i) for(int j=i;j<=n;++j) dp[i][j]=0; dp[1][n]=1;
for(int len=n;len>=1;--len){
for(int l=1, r=l+len-1;r<=n;++l, ++r){
v=pre[r]^pre[l-1]; v|=1ll<<61;
dp[l][r]|=(L[l]&v),dp[l][r]|=(R[r]&v);
if(dp[l][r]) L[l]|=lowbit(v), R[r]|=lowbit(v);
}
}
for(int i=1;i<=n;++i) putchar('0'+dp[i][i]); puts("");
}
int main(){
int t; scanf("%d",&t);while(t--) solve();
}
水题解