Codeforces Round #498 (Div. 3) - F Xor-Paths (折半搜索)

题目

题意:

给你一个n*m的矩阵,从(1,1)到(n,m)只能往右或者往下走,把路径的值全部异或起来,若等于k,则算作一条路径。

问你有几条路径。

POINT:

反搜一半得到DP[x][y][mod]的值,代表若走到xy这个点,值为mod对答案有多少贡献。

然后正搜到xy。

折半搜索。

注意x+y/2=1的情况。

起点为(1,1) x+y=2。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
using namespace std;
#define  LL long long
LL mp[33][33];
map<LL,LL>dp[33][33];

LL ans=0;
LL k;

void dfs(LL x,LL y,LL now,LL n,LL m)
{
	if(x>n||y>m) return;
	if(x+y>(n+m)/2+1) return;
	if(x+y==(n+m)/2+1){
		ans+=dp[x][y][now];
		return;
	}
	dfs(x+1,y,now^mp[x+1][y],n,m);
	dfs(x,y+1,now^mp[x][y+1],n,m);
}

void ddfs(LL x,LL y,LL now,LL n,LL m)
{
	if(x<1||y<1) return;
	if(x+y<(n+m)/2+1) return;
	now=now^mp[x][y];
	if(x+y==(n+m)/2+1){
		dp[x][y][now^mp[x][y]]++;
		return;
	}
	ddfs(x-1,y,now,n,m);
	ddfs(x,y-1,now,n,m);
}

int main()
{
	LL n,m;
	scanf("%lld%lld%lld",&n,&m,&k);
	for(LL i=1;i<=n;i++){
		for(LL j=1;j<=m;j++)
			scanf("%lld",&mp[i][j]);
	}
	ddfs(n,m,k,n,m);
	dfs(1,1,mp[1][1],n,m);
	printf("%lld\n",ans);



	return 0;
}

猜你喜欢

转载自blog.csdn.net/mr_treeeee/article/details/81079583