HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
2017-09-02 13:28
513 查看
题目:
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 , son[N*35][2], sum[N*35]; int tot; int len = 31; bool bs[35]; int cnt, head ; int num, in , out ; int a ; 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 ; int a , ans ; struct node { node *next[2]; node() { memset(next, 0, sizeof next); } }; node *root ; struct qnode { int x, id; qnode(int _x=0, int _id=0):x(_x), id(_id){} }; vector<qnode> vec ; 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; }
相关文章推荐
- hdu 6191 Query on A Tree(字典树启发式合并(动态建树) 可持久化字典树+dfs序)
- HDU 6191 Query on A Tree (dfs序+可持久化01Trie)
- 【HDU - 6191 】Query on A Tree 【 可持久01Trie +DFS序 】
- HDU 6191 && 2017广西邀请赛:Query on A Tree(字典树启发式合并)
- HDU - 6191 Query on A Tree 可持久化字典树+dfs序
- HDU 6191 Query on A Tree ( DFS序 + 可持久化字典树 )
- 2017 广西邀请赛&& hdu 6191 Query on A Tree(字典树启发式合并)
- [hdu 6191 Query on A Tree] 字典树启发式合并
- HDU - 6191 - Query on A Tree (可持久化Trie)
- hdu 6191 Query on A Tree(dfs序+可持久化字典树)
- 2017 icpc广西邀请赛 K.Query on A Tree (hdu 6191)可持久化字典树
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- HDU 6191 Query on A Tree [可持久化字典树]
- HDU - 6191 Query on A Tree 可持久化Tire
- HDU - 6191 Query on A Tree(可持久化字典树)
- HDU - 6191 Query on A Tree 可持久化字典树(01Trie) || 字典树启发式合并
- hdu 4670 Cube number on a tree,平衡树,启发式合并
- HDU 6191 Query on A Tree(字典树)
- HDU 6191 Query on A Tree
- hdu 4836:The Query on the Tree(巧妙dfs序)