HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
来源:互联网 发布:锁屏主题软件 编辑:程序博客网 时间:2024/05/21 19:48
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=6191
题意:
给出一棵树,树上每个点有点权,每次询问给出u x,求以u为根的子树中点权和x异或得到的最大值
思路:
dfs序建可持久化trie,然后就和普通可持久化trie一样了。还有启发式合并做法,一会学一下
#include <bits/stdc++.h>using namespace std;const int N = 100000 + 10;int root[N], son[N*35][2], sum[N*35];int tot;int len = 31;bool bs[35];int cnt, head[N];int num, in[N], out[N];int a[N];struct edge{ int to, next;}g[N*2];void init(){ cnt = 0; memset(head, -1, sizeof head); tot = 0; num = 0;}void add_edge(int v, int u){ g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;}void trie_insert(int p, int pre, int &x){ x = ++tot; son[x][0] = son[pre][0], son[x][1] = son[pre][1]; //memcpy(son[x], son[pre], sizeof(int) * 2); sum[x] = sum[pre] + 1; if(! p) return; trie_insert(p-1, son[pre][bs[p-1]], son[x][bs[p-1]]);}int trie_query(int p, int st, int en){ if(! p) return 0; if(sum[son[en][bs[p-1]]] > sum[son[st][bs[p-1]]]) return trie_query(p-1, son[st][bs[p-1]], son[en][bs[p-1]]) + (1<<(p-1)); return trie_query(p-1, son[st][1-bs[p-1]], son[en][1-bs[p-1]]);}void dfs(int v, int fa){ in[v] = ++num; for(int i = len-1; i >= 0; i--) bs[i] = 1 & (a[v] >> i); trie_insert(len, root[in[v]-1], root[in[v]]); for(int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if(u == fa) continue; dfs(u, v); } out[v] = num;}int main(){ int n, m; while(~ scanf("%d%d", &n, &m)) { init(); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); int x, u; for(int i = 1; i <= n-1; i++) { scanf("%d", &x); add_edge(x, i+1); } dfs(1, 0); for(int i = 1; i <= m; i++) { scanf("%d%d", &u, &x); for(int j = len-1; j >= 0; j--) bs[j] = ! (1 & (x >> j)); int ans = trie_query(len, root[in[u]-1], root[out[u]]); printf("%d\n", ans); } }}
//2017.9.2 17:08
对于一个点,访问过它的子树后,就把子树的字典树合并到当前点的字典树上去,然后就可以查询以当前点为子树的查询了,是一种离线算法
#include <bits/stdc++.h>using namespace std;const int N = 100000 + 10;int len = 31;int cnt, head[N];int a[N], ans[N];struct node{ node *next[2]; node() { memset(next, 0, sizeof next); }};node *root[N];struct qnode{ int x, id; qnode(int _x=0, int _id=0):x(_x), id(_id){}};vector<qnode> vec[N];struct edge{ int to, next;}g[N*2];void init(){ cnt = 0; memset(head, -1, sizeof head);}void add_edge(int v, int u){ g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;}void trie_insert(node *root, int val){ node *p = root; for(int i = len-1; i >= 0; i--) { int j = 1 & (val >> i); if(p->next[j] == NULL) p->next[j] = new node(); p = p->next[j]; }}int trie_query(node *root, int val){ node *p = root; int ans = 0; for(int i = len-1; i >= 0; i--) { int j = ! (1 & (val >> i)); if(p->next[j]) { p = p->next[j]; ans |= (1<<i); } else p = p->next[!j]; } return ans;}node* trie_merge(node *p, node *q){ if(! p) return q; if(! q) return p; p->next[0] = trie_merge(p->next[0], q->next[0]); p->next[1] = trie_merge(p->next[1], q->next[1]); free(q); return p;}void trie_del(node *p){ for(int i = 0; i < 2; i++) if(p->next[i]) trie_del(p->next[i]); free(p);}void dfs(int v, int fa){ root[v] = new node(); trie_insert(root[v], a[v]); for(int i = head[v]; ~i; i = g[i].next) { int u = g[i].to; if(u == fa) continue; dfs(u, v); root[v] = trie_merge(root[v], root[u]); } for(size_t i = 0; i < vec[v].size(); i++) ans[vec[v][i].id] = trie_query(root[v], vec[v][i].x);}int main(){ int n, m; while(~ scanf("%d%d", &n, &m)) { init(); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); int u, x; for(int i = 1; i <= n-1; i++) { scanf("%d", &x); add_edge(x, i+1); } for(int i = 1; i <= m; i++) { scanf("%d%d", &u, &x); vec[u].push_back(qnode(x, i)); } dfs(1, 0); for(int i = 1; i <= m; i++) printf("%d\n", ans[i]); trie_del(root[1]); for(int i = 1; i <= n; i++) vec[i].clear(); } return 0;}
阅读全文
0 0
- HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
- hdu 6191 Query on A Tree(字典树启发式合并(动态建树) 可持久化字典树+dfs序)
- HDU 6191 Query on A Tree (dfs序+可持久化01Trie)
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- HDU 6191 Query on A Tree ( DFS序 + 可持久化字典树 )
- [hdu 6191 Query on A Tree] 字典树启发式合并
- 不正常国家 (树链剖分 可持久化Trie 启发式合并)
- hdu 4757 Tree(可持久化Trie)
- HDU 6191 && 2017广西邀请赛:Query on A Tree(字典树启发式合并)
- 2017 广西邀请赛&& hdu 6191 Query on A Tree(字典树启发式合并)
- 2017 icpc广西邀请赛 K.Query on A Tree (hdu 6191)可持久化字典树
- HDU 6191 Query on A Tree [可持久化字典树]
- HDU 4757 Tree 可持久化trie+lca
- 2017ACM/ICPC广西邀请赛 K- Query on A Tree trie树合并
- 可持久化trie
- HDU-5801 可持久化Trie树
- HDU 4757 可持久化trie树
- HDU 6191 2017广西邀请赛Query on A Tree:可持久化01字典树(区间抑或最大值查询)
- QT中的图片透明
- Beginning Spring学习笔记——第8章 Spring AOP
- LeetCode
- [杂记] bsp与apk
- 生存期
- HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
- Android中数值计算的精度
- springMVC
- 从头开始学算法:考研机试题练习(C/C++)--入门模拟
- QT文字绘制
- 使用PullToRefresh遇到的问题
- PHP laravel系列之中间件
- 解决的s2010空间丑陋,解决manifest xp不显示控件的方法
- C++访问控制