题目链接:筱玛的迷阵探险

数据量比较小,于是可以想到爆搜,但是复杂度为 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;
}