Description
筱玛是个快乐的男孩子。
寒假终于到了,筱玛决定请他的朋友们一起来玩迷阵探险。
迷阵可以看做一个n×n
的矩阵A,每个格子上有一个有一个数Ai,j。
入口在左上角的(1,1)处,出口在右下角的(n,n)处。每一步都只能向下或向右移动一格。最后能获得的经验值为初始经验e与路径上经过的所有数的权值异或和。
求筱玛最大可能获得的经验值。
1≤n≤20;0≤e,Ai,j<231
Solution
A掉前三题就可rk20了233
非常巧妙的做法。我们折半搜出所有结果,一半扔在trie上,另一半查询相应最大异或值就可以了
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
typedef long long LL;
const int N=10000005;
struct treeNode {
int son[2],sz;
} t[N];
int tot,ans;
struct Tree {
int rt;
void ins(int v) {
if (!rt) rt=++tot;
int x=rt;
drp(i,30,0) {
t[x].sz++;
int k=((v>>i)&1);
if (!t[x].son[k]) t[x].son[k]=++tot;
x=t[x].son[k];
}
t[x].sz++;
}
int ask(int v) {
int x=rt,res=0;
drp(i,30,0) {
int k=((v>>i)&1);
if (t[t[x].son[!k]].sz) {
k^=1; res+=(1<<i);
}
x=t[x].son[k];
}
return res;
}
} T[21];
int a[21][21],id[21][21],n,e;
void dfs1(int x,int y,int d,int S) {
if (d==n) {
T[id[x][y]].ins(S);
return ;
}
dfs1(x+1,y,d+1,S^a[x+1][y]);
dfs1(x,y+1,d+1,S^a[x][y+1]);
}
void dfs2(int x,int y,int d,int S) {
if (d==n) {
ans=std:: max(ans,T[id[x][y]].ask(S^a[x][y]));
return ;
}
dfs2(x-1,y,d+1,S^a[x-1][y]);
dfs2(x,y-1,d+1,S^a[x][y-1]);
}
int main(void) {
freopen("data.in","r",stdin);
freopen("myp.out","w",stdout);
scanf("%d%d",&n,&e);
rep(i,1,n) id[i][n-i+1]=i;
rep(i,1,n) rep(j,1,n) scanf("%d",&a[i][j]);
if (n==1) {printf("%d\n", a[1][1]^e); return 0;}
dfs1(1,1,1,e^a[1][1]);
dfs2(n,n,1,a[n][n]);
printf("%d\n", ans);
return 0;
}