字典树+折半+贪心--牛客练习赛37 C 筱玛的迷阵探险

牛客练习赛37 C 筱玛的迷阵探险

参考博客

链接:

https://ac.nowcoder.com/acm/contest/342/C

来源:牛客网

题目描述

筱玛是个快乐的男孩子。
寒假终于到了,筱玛决定请他的朋友们一起来玩迷阵探险。
迷阵可以看做一个n×nn×n的矩阵A,每个格子上有一个有一个数Ai,j。
入口在左上角的(1,1)处,出口在右下角的(n,n)处。每一步都只能向下或向右移动一格。最后能获得的经验值为初始经验e与路径上经过的所有数的权值异或和。
求筱玛最大可能获得的经验值。

输入描述:

第一行两个整数n和e。
接下来n行,每行n个整数,描述矩阵A。

输出描述:

一个整数,表示筱玛最大可能获得的经验值。

示例1

输入

复制

5 2
3 4 7 2 6
3 5 2 9 0
3 8 5 7 3
2 5 3 1 4
9 8 6 3 5

输出

复制

15

备注:

1≤n≤20;0≤e,Ai,j<231

思路

折半,字典树。

从左上角遍历到对角线停止,用字典树存对角上每个点的所有可能值。

再从右下角往对角线遍历,到对角线时,贪心找字典树上每位数都为1的值,再异或算答案

有人说注意字典树大小

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 5e6 + 50;
const int MOD = 1e9 + 9;

#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)

int n;
LL mp[30][30], ans, e;
int tree[30][N][2], cnt;

void Add(int id, LL num)
{
    int rt = 0;
    RF(i, 30, 0)
    {
        int t = (num >> i) & 1;
        if(!tree[id][rt][t]) tree[id][rt][t] = ++cnt;//这里写成cnt++就错了,注意字典树模板
        rt = tree[id][rt][t];
    }
}

LL solve(int id, LL num)
{
    LL rt = 0, ret = 0;
    RF(i, 30, 0)
    {
        int t = (num >> i) & 1;
        if(tree[id][rt][t ^ 1]) {ret += (1ll << i);rt = tree[id][rt][t ^ 1];}
        else rt = tree[id][rt][t];
    }
    return ret;
}

void dfs1(int x, int y, LL val)
{
    if(x + y == n + 1) {Add(x, val ^ mp[x][y]);return ;}
    if(y + 1 <= n) dfs1(x, y + 1, val ^ mp[x][y]);
    if(x + 1 <= n) dfs1(x + 1, y, val ^ mp[x][y]);
}

void dfs2(int x, int y, LL val)
{
    if(x + y == n + 1) {ans = max(ans, solve(x, val));return ;}
    if(y - 1 > 0) dfs2(x, y - 1, val ^ mp[x][y]);
    if(x - 1 > 0) dfs2(x - 1, y, val ^ mp[x][y]);
}

int main()
{
    cin >> n >> e;
    F(i, 1, n) F(j, 1, n) cin >> mp[i][j];
    dfs1(1, 1, e);dfs2(n, n, 0);
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/shuizhidao/p/10802962.html