1. 程式人生 > >寒假訓練——搜索 G - Xor-Paths

寒假訓練——搜索 G - Xor-Paths

namespace The 兩種 outside formal tdi \n type java

There is a rectangular grid of size n×mn×m . Each cell has a number written on it; the number on the cell (i,ji,j ) is ai,jai,j . Your task is to calculate the number of paths from the upper-left cell (1,11,1 ) to the bottom-right cell (n,mn,m ) meeting the following constraints:

  • You can move to the right or to the bottom only. Formally, from the cell (
    i,ji,j ) you may move to the cell (i,j+1i,j+1 ) or to the cell (i+1,ji+1,j ). The target cell can‘t be outside of the grid.
  • The xor of all the numbers on the path from the cell (1,11,1 ) to the cell (n,mn,m ) must be equal to kk (xor operation is the bitwise exclusive OR, it is represented as ‘^‘ in Java or C++ and "xor" in Pascal).

Find the number of such paths in the given grid.

Input

The first line of the input contains three integers nn , mm and kk (1n,m201≤n,m≤20 , 0k10180≤k≤1018 ) — the height and the width of the grid, and the number kk .

The next nn lines contain mm integers each, the jj -th element in the ii -th line is

ai,jai,j (0ai,j10180≤ai,j≤1018 ).

Output

Print one integer — the number of paths from (1,11,1 ) to (n,mn,m ) with xor sum equal to kk .

Examples

Input
3 3 11
2 1 5
7 10 0
12 6 4
Output
3
Input
3 4 2
1 3 3 3
0 3 3 2
3 0 1 1
Output
5
Input
3 4 1000000000000000000
1 3 3 3
0 3 3 2
3 0 1 1
Output
0

Note

All the paths from the first example:

  • (1,1)(2,1)(3,1)(3,2)(3,3)(1,1)→(2,1)→(3,1)→(3,2)→(3,3) ;
  • (1,1)(2,1)(2,2)(2,3)(3,3)(1,1)→(2,1)→(2,2)→(2,3)→(3,3) ;
  • (1,1)(1,2)(2,2)(3,2)(3,3)(1,1)→(1,2)→(2,2)→(3,2)→(3,3) .

All the paths from the second example:

  • (1,1)(2,1)(3,1)(3,2)(3,3)(3,4)(1,1)→(2,1)→(3,1)→(3,2)→(3,3)→(3,4) ;
  • (1,1)(2,1)(2,2)(3,2)(3,3)(3,4)(1,1)→(2,1)→(2,2)→(3,2)→(3,3)→(3,4) ;
  • (1,1)(2,1)(2,2)(2,3)(2,4)(3,4)(1,1)→(2,1)→(2,2)→(2,3)→(2,4)→(3,4) ;
  • (1,1)(1,2)(2,2)(2,3)(3,3)(3,4)(1,1)→(1,2)→(2,2)→(2,3)→(3,3)→(3,4) ;
  • (1,1)(1,2)(1,3)(2,3)(3,3)(3,4)(1,1)→(1,2)→(1,3)→(2,3)→(3,3)→(3,4) .

題目:G - Xor-Paths
思路:
折半思想,前一半:從位置(1,1)開始到x+y=(n+m)/2,可以看成函數,進行異或。
後一半:從(n,m)開始,一直到x+y=(n+m)/2,異或。
異或有交換律,還有其他運算法則。
由運算法則可以推出公式
k=a1^a2^...^an;
令i=(1+n)/2;
q=a1^a2^...^ai;
sum=ai^...^an;
k=sum^ai^q;
所以q=sum^ai^k;
然後你第一個函數在走到的點給sum值打個標記,然後第二個函數把sum^ai就是取消這一步的值(這個值在前一個函數)
再^k就是找到跟現在這個sum異或起來為k(也就是合成一條路徑)標記的值,也就是方案有多少
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=25;
ll a[maxn][maxn],ans,k;
map<ll,ll>mp[maxn];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int n,m;
void dfs_pre(int x,int y,ll sum)
{
    if(x+y==(n+m+2)/2) {mp[x][sum]++;return ;}//x+y==(n+m+2)/2,有個+2是因為有兩種特殊情況,一個是n=1,一個是m=1
    for(int i=0;i<2;i++)
    {
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(tx<1||ty<1||tx>n||ty>m) continue;
        dfs_pre(tx,ty,sum^a[tx][ty]);
    }
}
void dfs_end(int x,int y,ll sum)
{
    if(x+y==(n+m+2)/2) {ans+=mp[x][sum^k^a[x][y]];return ;}
    for(int i=2;i<4;i++)
    {
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(tx<1||ty<1||tx>n||ty>m) continue;
        dfs_end(tx,ty,sum^a[tx][ty]);
    }
}

int main()
{
    scanf("%d%d%I64d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%I64d",&a[i][j]);
        }
    }
    dfs_pre(1,1,a[1][1]);
    dfs_end(n,m,a[n][m]);
    printf("%I64d\n",ans);
    return 0;
}

  

寒假訓練——搜索 G - Xor-Paths