ABC 271 F – XOR on Grid Path题意:

​给出20 * 20的地图,每个点上都有一个点权,保证为正整数。请问从(1, 1)走到(n, n)且路径上所有点权异或和为0的路径有多少条。

思路:

​本题利用了meet in the mid的思想。因为是(1, 1)到(n, n),所以一定会在某个中间的地方相遇。

​走到某点(x, y)会有很多种路径,以及很多个不同的异或和值。因为从(1, 1)走到(n, n)一共是2 * n步。

​我们预处理从(1, 1)只向右下走,走到(x, y),且步数为n的时候停止,并将异或和加入\(mp[x][y][val] ++\)

​然后再从(n, n)只向左上走,走到(x, y)的时候,如果此时的异或和有这样的值存在\(mp[x][y]\),就把方案数加上。

​这样做的时间复杂度是2 * C(20, 10),还有一个map的log复杂度。(用umap可能被卡到O(n),在CF慎用)。

实现:

\(map [x][y]\)为走到(x, y)的时候,他的不同的值和其方案数。

int n;int c[22][22];map mp[22][22];int res = 0;void dfs1(int x, int y, int step, int sum){    if (step == n)    {        mp[x][y][sum ^ c[x][y]]++; //最后一步        return;    }    if (x + 1 <= n)        dfs1(x + 1, y, step + 1, sum ^ c[x][y]);    if (y + 1 = 1)        dfs2(x - 1, y, step + 1, sum ^ c[x][y]);    if (y - 1 >= 1)        dfs2(x, y - 1, step + 1, sum ^ c[x][y]);}signed main(){    ios::sync_with_stdio(false);cin.tie(0);    cin >> n;    for (int i = 1; i <= n; i++)        for (int j = 1; j > c[i][j];    dfs1(1, 1, 1, 0);    dfs2(n, n, 1, 0);    cout << res << '\n';}