2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)J - Query on A Tree 字典树合并

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,⋯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

可持久化Trie ,启发式合并即可,

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
    long long  ans = 1;
    while (b) {
        if (b & 1)ans = ans * a;
        b >>= 1;
        a = a * a;
    }
    return ans;
}

inline int read() {
    int an = 0, x = 1; char c = getchar();
    while (c > '9' || c < '0') {
        if (c == '-') {
            x = -1; 
        }
        c = getchar();
    }
    while (c >= '0'&&c <= '9') {
        an = an * 10 + c - '0'; c = getchar();
    }
    return an * x;
}

struct ask {
    int u, id;
};
struct Trie {
    Trie *nxt[2];
    Trie() {
        nxt[0] = nxt[1] = NULL;
    }
};
int ans[maxn], val[maxn], n, q;
vector<int>G[maxn];
vector<ask>Q[maxn];
Trie *root[maxn];
void Insert(Trie *rt, int x) {
    int id;
    for (int i = 30; i >= 0; i--) {
        id = 0;
        if (x&(1 << i))id = 1;
        if (rt->nxt[id] == NULL) {
            Trie *tmp = new Trie();
            rt->nxt[id] = tmp;
        }
        rt = rt->nxt[id];
    }
}

int query(Trie *rt, int x) {
    int ret = 0, id;
    for (int i = 30; i >= 0; i--) {
        id = 0;
        if (x&(1 << i))id = 1;
        if (rt->nxt[id ^ 1] != NULL) {
            ret |= (1 << i);
            rt = rt->nxt[id ^ 1];
        }
        else {
            rt = rt->nxt[id];
        }
    }
    return ret;
}

Trie *merge(Trie *p, Trie *q) {
    if (p == NULL)return q;
    if (q == NULL)return p;
    p->nxt[0] = merge(p->nxt[0], q->nxt[0]);
    p->nxt[1] = merge(p->nxt[1], q->nxt[1]);
    free(q);
    return p;
}

void build(int u) {
    int v;
    root[u] = new Trie();
    Insert(root[u], val[u]);
    for (int i = 0; i < G[u].size(); i++) {
        v = G[u][i];
        build(v);
        root[u] = merge(root[u], root[v]);
    }
    for (int i = 0; i < Q[u].size(); i++) {
        ans[Q[u][i].id] = query(root[u], Q[u][i].u);
    }
}

void det(Trie *rt) {
    if (rt->nxt[0])det(rt->nxt[0]);
    if (rt->nxt[1])det(rt->nxt[1]);
    free(rt);
}

void sol() {
    int u, x;
    ask tmp;
    for (int i = 1; i <= n; i++) {
        G[i].clear();
        Q[i].clear();
        cin >> val[i];
    }
    for (int i = 2; i <= n; i++) {
        cin >> x;
        G[x].push_back(i);
    }
    for (int i = 1; i <= q; i++) {
        cin >> u >> x;
        tmp.u = x;
        tmp.id = i;
        Q[u].push_back(tmp);
    }
    build(1);
    for (int i = 1; i <= q; i++)cout << ans[i] << endl;
    det(root[1]);
}

int main() {
    ios::sync_with_stdio(false);
    while (cin >> n >> q) {
        sol();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/81570798