2017广西邀请赛Query on A Tree(可持久化字典树)

xiaoxiao2021-02-28  114

题意:给你一棵树,每个节点一个权值,然后m次查询,每次查询以u为根节点的子树上的某点与x异或的最大值。

题解:比赛时死活不会写,当时没学可持久化字典树,暴力写了一发,然后无限TLE。。。其实就是一道可持久化字典树模板题,我们可以将树上的权值转化为区间问题,呢就用DFS序好了,剩下的跑一发可持久化字典树就OK了。

#include<set> #include<map> #include<stack> #include<queue> #include<vector> #include<string> #include<math.h> #include<stdio.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<algorithm> #include<functional> using namespace std; typedef long long ll; #define inf 1000000000 #define mod 1000000007 #define maxn 260005 #define PI acos(-1.0) #define lowbit(x) (x&-x) #define eps 1e-9 vector<int>q[maxn]; int n, m, t, a[maxn], id[maxn], rt[maxn], st[maxn], ed[maxn], b[maxn]; struct node { int cnt; int ch[maxn * 32][2], sum[maxn * 32]; void init() { cnt = 0;b[0] = 1; for (int i = 1;i <= 30;i++) b[i] = b[i - 1] * 2; memset(ch, 0, sizeof(ch)); memset(sum, 0, sizeof(sum)); } int insert(int x, int val) { int res, y; y = res = ++cnt; for (int i = 30;i >= 0;i--) { ch[y][0] = ch[x][0]; ch[y][1] = ch[x][1]; sum[y] = sum[x] + 1; int tmp = val&b[i]; tmp >>= i;x = ch[x][tmp]; ch[y][tmp] = ++cnt;y = ch[y][tmp]; } sum[y] = sum[x] + 1; return res; } int query(int l, int r, int val) { int ans = 0; for (int i = 30;i >= 0;i--) { int tmp = val&b[i]; tmp >>= i; if (sum[ch[r][tmp ^ 1]] - sum[ch[l][tmp ^ 1]]) ans += b[i], l = ch[l][tmp ^ 1], r = ch[r][tmp ^ 1]; else l = ch[l][tmp], r = ch[r][tmp]; } return ans; } }trie; void dfs(int u, int p) { st[u] = ++t; id[t] = u; for (int i = 0;i < q[u].size();i++) { int v = q[u][i]; if (v == p) continue; dfs(v, u); } ed[u] = t; } int main(void) { int i, j, x; while (scanf("%d%d", &n, &m) != EOF) { t = 0;rt[0] = 0; trie.init(); for (i = 1;i <= n;i++) scanf("%d", &a[i]), q[i].clear(); for (i = 2;i <= n;i++) { scanf("%d", &x); q[x].push_back(i); } dfs(1, 0); for (i = 1;i <= n;i++) rt[i] = trie.insert(rt[i - 1], a[id[i]]); int l, r, root, x; while (m--) { scanf("%d%d", &root, &x); l = st[root];r = ed[root]; printf("%d\n", trie.query(rt[l - 1], rt[r], x)); } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-45325.html

最新回复(0)