题目链接:筱玛的迷阵探险
数据量比较小,于是可以想到爆搜,但是复杂度为 2^40,必然不行,于是对于二进制求max,我们可以想到用Trie去维护。
怎么做呢?我们双向dfs,对每一个走到 n/2 步数的节点分别开一个Trie,然后下一次从终点走到这个节点时,然后从这个节点当中的Trie里面去找max。
总复杂度为: 2^20 * 30 完全ok。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=6e6+10;
int n,e,g[25][25],t[25][N][2],idx,res;
inline void insert(int x,int id){
int p=0;
for(int i=30;i>=0;i--){
int k=(x>>i&1);
if(!t[id][p][k]) t[id][p][k]=++idx; p=t[id][p][k];
}
}
inline int ask(int x,int id){
int res=0,p=0;
for(int i=30;i>=0;i--){
int k=(x>>i&1);
if(t[id][p][k^1]) res+=(1<<i),p=t[id][p][k^1];
else p=t[id][p][k];
}
return res;
}
void dfs1(int x,int y,int step,int s){
s^=g[x][y];
if(step==n){insert(s,x); return ;}
if(x<n) dfs1(x+1,y,step+1,s);
if(y<n) dfs1(x,y+1,step+1,s);
}
void dfs2(int x,int y,int step,int s){
if(step==n){res=max(res,ask(s,x)); return ;}
if(x!=1) dfs2(x-1,y,step+1,s^g[x][y]);
if(y!=1) dfs2(x,y-1,step+1,s^g[x][y]);
}
signed main(){
cin>>n>>e;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>g[i][j];
dfs1(1,1,1,e); dfs2(n,n,1,0);
cout<<res<<endl;
return 0;
}