题解 CF1006F 【Xor-Paths】
题意
给出一个矩阵,求出从左上角到右下角所经过的点的点权异或和为k的路径数
分析
首先我们发现
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
ll k,a[25][25],ans;
map<ll,ll> s[25][25];
void dfs1(int x,int y,ll sum)
{
if(x>n||y>m) return;
//以(n+m)/2+1为对角线,到达这里时就退出
if(x+y==(n+m)/2+1)
{
++s[x][y][sum];
return;
}
dfs1(x+1,y,a[x+1][y]^sum);
dfs1(x,y+1,a[x][y+1]^sum);
//只向下边和右边走
}
void dfs2(int x,int y,ll sum)
{
if(x<1||y<1) return;
if(x+y==(n+m)/2+1)
{
ans+=s[x][y][sum^k^a[x][y]];
/*一个小技巧,一个数异或两次等于没异或,从头到(x,y)
和从尾到(x,y)都异或了一次,在异或一次才算异或过它*/
return;
}
dfs2(x-1,y,a[x-1][y]^sum);
dfs2(x,y-1,a[x][y-1]^sum);
//反向dfs,只向上边和左边走
}
int main()
{
scanf("%d%d%lld",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&a[i][j]);
dfs1(1,1,a[1][1]);
dfs2(n,m,a[n][m]);
printf("%lld",ans);
return 0;
}