大概思路是对于每个状态开个set存有那些编号可以到这个节点,然后他神奇的过了11,12?但是会在3 WA掉,我看了一下正确性是假的,求问考场上能拿多少分(大概)
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
char op[22][100010];
int a[100010],w[100010],q[100010],x[5];
set<int>f[22][100010];
void solve(){
for(int i=0;i<4;i++)cin>>x[i];
for(int i=1;i<=n;i++)w[i]=a[i]^x[i%4];
int res=0;
for(int i=1;i<=m;i++){
int t=(int)(ceil(log2(q[i])));
for(int j=1;j<=(1<<t);j++)f[0][j].insert(j);
for(int j=1;j<=t;j++){
for(int k=1;k<=(1<<(t-j+1));k+=2){
int d=(k+1)/2;
if(op[j][d]=='0'){
if(*f[j-1][k].begin()<=q[i]){
if(f[j-1][k].size()==1&&w[*f[j-1][k].begin()]>=j){
for(auto it=f[j-1][k].begin();it!=f[j-1][k].end();it++)
f[j][d].insert(*it);
}else{
for(auto it=f[j-1][k+1].begin();it!=f[j-1][k+1].end();it++)
f[j][d].insert(*it);
}
}else{
for(auto it=f[j-1][k].begin();it!=f[j-1][k].end();it++)
f[j][d].insert(*it);
for(auto it=f[j-1][k+1].begin();it!=f[j-1][k+1].end();it++)
f[j][d].insert(*it);
}
}else{
if(*f[j-1][k+1].begin()<=q[i]){
if(w[*f[j-1][k+1].begin()]>=j){
for(auto it=f[j-1][k+1].begin();it!=f[j-1][k+1].end();it++)
f[j][d].insert(*it);
}else{
for(auto it=f[j-1][k].begin();it!=f[j-1][k].end();it++)
f[j][d].insert(*it);
}
}else{
for(auto it=f[j-1][k].begin();it!=f[j-1][k].end();it++)
f[j][d].insert(*it);
for(auto it=f[j-1][k+1].begin();it!=f[j-1][k+1].end();it++)
f[j][d].insert(*it);
}
}
}
}
int ans=0;
for(auto it=f[t][1].begin();it!=f[t][1].end();it++)
ans+=(*it);
for(int j=0;j<=t;j++)
for(int k=1;k<=(1<<(t-j+1));k++)
f[j][k].clear();
res=res^(ans*i);
}
cout<<res<<'\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++)cin>>q[i];
int k=(int)(ceil(log2(n)));
for(int i=1;i<=k;i++)
cin>>op[i]+1;
int T;
cin>>T;
while(T--)
solve();
return 0;
}