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 }
  • 相关阅读:
    ubuntu下安装chromium浏览器adobe flash插件
    Eclipse运行时提示failed to create the java virtual machine 解决方法
    64位Ubuntu下不能生成R.java文件的问题(Android)
    Ubuntu下Eclipse的中文支持(GBK)
    Android工程编译错误:The project cannot be built until build path errors are resolved
    Apache POI
    ubuntu下安装Google拼音输入法
    [导入]ThinkPHP新手推荐学习路线
    [导入]示例Blog发表日志的程序流程(总结)
    [导入][视频] ThinkPHP入门第一步
  • 原文地址:https://www.cnblogs.com/Penn000/p/7533078.html
Copyright © 2011-2022 走看看