HDU-6191 01字典树+启发式合并
来源:互联网 发布:盘点2016网络流行语 编辑:程序博客网 时间:2024/06/05 22:38
题目
Query on A Tree
题解
如果每次查询都是在整棵树查询的话,那么直接用01字典树就可以解决。但是如果查询是在某一子树的话,就没法在线的查询了,需要进行离线处理。用 dfs 从下向上建树,在遇到非叶子结点时,对其子节点进行合并。之所以叫启发式合并,是因为我们通常把将小向大的合并叫做启发式合并。
PS. 代码最后注释了一组样例,莫名WA的同学可以试试
代码
#include <algorithm>#include <bitset>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <climits>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>using namespace std;const int MAX = 100005;struct trieNode{ trieNode *to[2]; int num; long long val; trieNode(int num = 0, int val = 0){ memset(to,NULL, sizeof(to)); this->num = num; this->val = val; }};void inser(long long a, trieNode *u){ for(int i=32;i>=0;i--){ int c = ((a>>i)&1); if(u->to[c] == NULL){ u->to[c] = new trieNode(); } (u->to[c])->num++; u = u->to[c]; } u->val = a;}long long query(long long a,trieNode *u){ for(int i=32;i>=0;i--){ int c=((a>>i)&1); if(u->to[c^1] ) u = u->to[c^1]; else u = u->to[c]; } return u -> val;}void clear(trieNode *u){ if(u -> to[0]) clear(u -> to[0]); if(u -> to[1]) clear(u -> to[1]); free(u);}trieNode* Merge(trieNode *a, trieNode *b){ if(a == NULL) return b; if(b == NULL) return a; a -> to[0] = Merge(a -> to[0], b -> to[0]); a -> to[1] = Merge(a -> to[1], b -> to[1]); a -> num += b -> num; free(b); return a;}struct node{ int id; int x;};vector<struct node>v[MAX];int ans[MAX];struct MyMap{ struct edge{ int to,next,val; }edges[MAX]; int head[MAX]; int value[MAX]; int cnt; void init(){ cnt = 0; memset(head,-1,sizeof(head)); } void addEdge(int u, int v, int val){ edges[cnt].to = v; edges[cnt].val = val; edges[cnt].next = head[u]; head[u] = cnt++; } trieNode* dfs(int u){ trieNode *root = new trieNode(); for(int i=head[u];i != -1;i=edges[i].next){ int v = edges[i].to; trieNode* temp; temp = dfs(v); root = Merge(root,temp); } inser(value[u],root); int len = v[u].size(); for(int i=0;i<len;++i) { ans[v[u][i].id] = query(v[u][i].x,root) ^ v[u][i].x; } return root; }};MyMap myMap;int main(){ int n,q; while(cin >> n >> q){ myMap.init(); for(int i=1;i<=n;++i){ scanf("%d",&myMap.value[i]); v[i].clear(); } for(int i=1;i<=n-1;++i){ int x; scanf("%d",&x); myMap.addEdge(x, i+1, 0); } struct node temp; for(int i=0;i<q;++i){ int u,x; scanf("%d %d",&u,&x); temp.id = i; temp.x = x; v[u].push_back(temp); } clear(myMap.dfs(1)); for(int i=0;i<q;++i){ printf("%d\n",ans[i]); } } return 0;}/*2 21 211 32 111 41 2 3 4 5 6 7 8 9 10 111 1 1 2 2 3 4 4 4 52 53 61 28 7 */
阅读全文
0 0
- HDU-6191 01字典树+启发式合并
- [hdu 6191 Query on A Tree] 字典树启发式合并
- HDU 6191 && 2017广西邀请赛:Query on A Tree(字典树启发式合并)
- 2017 广西邀请赛&& hdu 6191 Query on A Tree(字典树启发式合并)
- hdu 6191 Query on A Tree(字典树启发式合并(动态建树) 可持久化字典树+dfs序)
- Hdu 6133 启发式合并
- HDU6191Query on A Tree(字典树启发式合并)
- hdu 4680 splay,启发式合并
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- 【HDU 5997】 rausen loves cakes 【启发式合并+线段树】
- 启发式合并&线段树合并&treap合并
- 伸展树的启发式合并
- Trie树练习题 启发式合并
- 启发式合并
- HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
- hdu 4670 Cube number on a tree,平衡树,启发式合并
- Hdu 3726 Graph and Queries(并查集+平衡树+启发式合并)
- HDU 5997 rausen loves cakes (线段树区间维护,启发式区间合并)
- yii缓存使用
- HDU
- 【python】LeetCode刷题 566. Reshape the Matrix
- win8 64位系统下的DNW驱动安装方法
- 从今天开始我的技术博客开张啦
- HDU-6191 01字典树+启发式合并
- heartbeat+drbd+mysql+keepalived
- 线程小结
- 数据结构学习笔记:B-/B+树
- python学习笔记--易忘点1
- 1017. A除以B (20)
- 【图像语义分割】Large Kernel Maters--Improved Semantic Segmentation by Global ConvNet
- 二分法之查找最接近目标数的数
- Java基础部分第一节_开发工具