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
原创粉丝点击