HDU6191(01字典树启发式合并)
Query on A Tree
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 801 Accepted Submission(s): 302
Problem Description
Monkey A lives on a tree, he always plays on this tree.
One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.
Monkey A gave a value to each node on the tree. And he was curious about a problem.
The problem is how large the xor result of number x and one node value of label y can be, when giving you a non-negative integer x and a node label u indicates that node y is in the subtree whose root is u(y can be equal to u).
Can you help him?
One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.
Monkey A gave a value to each node on the tree. And he was curious about a problem.
The problem is how large the xor result of number x and one node value of label y can be, when giving you a non-negative integer x and a node label u indicates that node y is in the subtree whose root is u(y can be equal to u).
Can you help him?
Input
There are no more than 6 test cases.
For each test case there are two positive integers n and q, indicate that the tree has n nodes and you need to answer q queries.
Then two lines follow.
The first line contains n non-negative integers V1,V2,⋯,Vn, indicating the value of node i.
The second line contains n-1 non-negative integers F1,F2,⋯Fn−1, Fi means the father of node i+1.
And then q lines follow.
In the i-th line, there are two integers u and x, indicating that the node you pick should be in the subtree of u, and x has been described in the problem.
2≤n,q≤105
0≤Vi≤109
1≤Fi≤n, the root of the tree is node 1.
1≤u≤n,0≤x≤109
For each test case there are two positive integers n and q, indicate that the tree has n nodes and you need to answer q queries.
Then two lines follow.
The first line contains n non-negative integers V1,V2,⋯,Vn, indicating the value of node i.
The second line contains n-1 non-negative integers F1,F2,⋯Fn−1, Fi means the father of node i+1.
And then q lines follow.
In the i-th line, there are two integers u and x, indicating that the node you pick should be in the subtree of u, and x has been described in the problem.
2≤n,q≤105
0≤Vi≤109
1≤Fi≤n, the root of the tree is node 1.
1≤u≤n,0≤x≤109
Output
For each query, just print an integer in a line indicating the largest result.
Sample Input
2 2
1 2
1
1 3
2 1
Sample Output
2
3
Source
题意:给一棵树,树上每个节点有一个权值。然后有q次查询,每次查询给你节点标号u和一个数x。问以u的子树里面的所有节点点权和数x的最大异或值是多少。
思路:使用01字典树解决异或值最大问题,使用字典树的合并,可得到每棵子树上的异或最大值。
1 //2017-09-16 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 8 using namespace std; 9 10 const int N = 110000; 11 int head[N], tot; 12 struct Edge{ 13 int v, next; 14 }edge[N]; 15 16 void init(){ 17 tot = 0; 18 memset(head, -1, sizeof(head)); 19 } 20 21 void add_edge(int u, int v){ 22 edge[tot].v = v; 23 edge[tot].next = head[u]; 24 head[u] = tot++; 25 } 26 27 int n, q, arr[N]; 28 int ans[N]; 29 vector< pair<int, int> > qy[N]; 30 struct Trie{ 31 Trie* next[2]; 32 }*root[N]; 33 34 void insert(Trie* rt, int x){ 35 for(int i = 31; i >= 0; i--){ 36 int idx = (x>>i)&1; 37 if(rt->next[idx] == NULL){ 38 Trie *tmp = new Trie(); 39 rt->next[idx] = tmp; 40 } 41 rt = rt->next[idx]; 42 } 43 } 44 45 int query(Trie* rt, int x){ 46 int ans = 0; 47 for(int i = 31; i >= 0; i--){ 48 int idx = (x>>i)&1; 49 if(rt->next[idx^1] != NULL){ 50 rt = rt->next[idx^1]; 51 ans |= (1<<i); 52 }else rt = rt->next[idx]; 53 } 54 return ans; 55 } 56 57 Trie* merge(Trie* p, Trie* q){ 58 if(p == NULL)return q; 59 if(q == NULL)return p; 60 p->next[0] = merge(p->next[0], q->next[0]); 61 p->next[1] = merge(p->next[1], q->next[1]); 62 free(q); 63 return p; 64 } 65 66 void dfs(int u, int fa){ 67 root[u] = new Trie(); 68 insert(root[u], arr[u]); 69 for(int i = head[u]; i != -1; i = edge[i].next){ 70 int v = edge[i].v; 71 if(v == fa)continue; 72 dfs(v, u); 73 root[u] = merge(root[u], root[v]); 74 } 75 for(auto &q: qy[u]){ 76 ans[q.first] = query(root[u], q.second); 77 } 78 } 79 80 void clear(Trie* rt){ 81 if(rt->next[0]) clear(rt->next[0]); 82 if(rt->next[1]) clear(rt->next[1]); 83 free(rt); 84 } 85 86 int main() 87 { 88 while(scanf("%d%d", &n, &q) != EOF){ 89 init(); 90 for(int i = 1; i <= n; i++){ 91 scanf("%d", &arr[i]); 92 qy[i].clear(); 93 } 94 int v; 95 for(int i = 2; i <= n; i++){ 96 scanf("%d", &v); 97 add_edge(v, i); 98 } 99 int u, x; 100 for(int i = 0; i < q; i++){ 101 scanf("%d%d", &u, &x); 102 qy[u].push_back(make_pair(i, x)); 103 } 104 dfs(1, -1); 105 for(int i = 0; i < q; i++) 106 printf("%d\n", ans[i]); 107 clear(root[1]); 108 } 109 110 return 0; 111 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2016-09-16 HDU2063(二分图最大匹配)
2016-09-16 HDU4738(割边)
2016-09-16 POJ1144(割点)
2016-09-16 POJ1556(割点)