zoukankan      html  css  js  c++  java
  • 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?
     

    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,Fn1Fi 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.

    2n,q105

    0Vi109

    1Fin, the root of the tree is node 1.

    1un,0x109
     

    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
    ", ans[i]);
    107         clear(root[1]);
    108     }
    109 
    110     return 0;
    111 }
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/Penn000/p/7533078.html
Copyright © 2011-2022 走看看