题解 CF1006F 【Xor-Paths】

· · 题解

大水题一道。首先考虑直接爆搜,肯定会超时不用想,复杂度高达 $2^{40}$,但是如果对其折半的话,就是 $2\times2^{20}$ 的复杂度,这个是完全可以接受的,所以我们矩阵折半,从 右上-左下 对角线分开,先搜左上这一块,把搜出的异或和记录在 $\texttt{map}$ 里,再搜右下角,假如我们搜出的异或和为 $\text{cnt}$,那么我们只需要找一下 $\texttt{map}$ 里有多少个 $\text{k xor cnt}$ 与之对应即可。 ```cpp #include<bits/stdc++.h> #define MAXN 25 #define reg register #define inl inline #define int long long using namespace std; map <int,int> mp[MAXN][MAXN]; int n,m,k,a[MAXN][MAXN],lim,ans; void Dfs1(reg int x,reg int y,reg int cnt) { if(x<1 || x>n || y<1 || y>m) return; cnt^=a[x][y]; if(x+y==lim) { mp[x][y][cnt]++; return; } Dfs1(x+1,y,cnt); Dfs1(x,y+1,cnt); } void Dfs2(reg int x,reg int y,reg int cnt) { if(x<1 || x>n || y<1 || y>m) return; if(x+y==lim) { ans+=mp[x][y][cnt^k]; return; } cnt^=a[x][y]; Dfs2(x-1,y,cnt); Dfs2(x,y-1,cnt); } signed main() { scanf("%lld %lld %lld",&n,&m,&k); for(reg int i=1;i<=n;i++) { for(reg int j=1;j<=m;j++) scanf("%lld",&a[i][j]); } lim=(n+m+2)/2; Dfs1(1,1,0); Dfs2(n,m,0); printf("%lld\n",ans); return 0; } ```