• HDU 6191 Query on A Tree(可持久化Trie+DFS序)


    Query on A Tree

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
    Total Submission(s): 712    Accepted Submission(s): 266

    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
     

    题目链接:HDU 6191

    本来以为是很水的一道题目(确实很水),结果被坑在update的构建顺序上WA了很久,因为是可持久化,需要上一个版本的信息,而恰好一开始是先DFS序,再for每一个元素用它的L[i]时间戳来构建,其实这是有问题的, 因为上一个元素的L[i]不一定跟当前的L[i]连续,因此要按照L[i]的顺序来构建,而不是i的顺序;构建好之后查询一下L[u]~R[u]之间的与x的异或最大值即可

    代码:

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <climits>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define fin(name) freopen(name,"r",stdin)
    #define fout(name) freopen(name,"w",stdout)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 100010;
    struct edge
    {
        int to, nxt;
        edge() {}
        edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
    } E[N];
    struct Trie
    {
        int nxt[2];
        int cnt;
        void init()
        {
            nxt[0] = nxt[1] = 0;
            cnt = 0;
        }
    } L[N * 31];
    int tot, root[N];
    int head[N], etot;
    int ll[N], rr[N], idx;
    int arr[N];
    
    void init()
    {
        L[0].init();
        tot = 0;
        CLR(head, -1);
        etot = 0;
        idx = 0;
    }
    inline void add(int s, int t)
    {
        E[etot] = edge(t, head[s]);
        head[s] = etot++;
    }
    void update(int &cur, int ori, int step, LL n, int v)
    {
        cur = ++tot;
        L[cur] = L[ori];
        L[cur].cnt += v;
        if (step < 0)
            return ;
        int t = (n >> step) & 1;
        update(L[cur].nxt[t], L[ori].nxt[t], step - 1, n, v);
    }
    int Find(int S, int E, int step, LL n)
    {
        if (step < 0)
            return 0;
        int t = (n >> step) & 1;
        if (L[L[E].nxt[t ^ 1]].cnt - L[L[S].nxt[t ^ 1]].cnt > 0)
            return (1LL << step) + Find(L[S].nxt[t ^ 1], L[E].nxt[t ^ 1], step - 1, n);
        else
            return Find(L[S].nxt[t], L[E].nxt[t], step - 1, n);
    }
    void dfs_build(int u)
    {
        ll[u] = ++idx;
        update(root[ll[u]], root[ll[u] - 1], 29, arr[u], 1);
        for (int i = head[u]; ~i; i = E[i].nxt)
        {
            int v = E[i].to;
            dfs_build(v);
        }
        rr[u] = idx;
    }
    int main(void)
    {
        int n, q, i;
        while (~scanf("%d%d", &n, &q))
        {
            init();
            for (i = 1; i <= n; ++i)
                scanf("%d", &arr[i]);
            for (i = 2; i <= n; ++i)
            {
                int f;
                scanf("%d", &f);
                add(f, i);
            }
            dfs_build(1);
            while (q--)
            {
                int u, x;
                scanf("%d%d", &u, &x);
                int l = ll[u], r = rr[u];
                printf("%d
    ", Find(root[l - 1], root[r], 29, x));
            }
        }
        return 0;
    }
  • 相关阅读:
    linux系统缓存机制
    信号“未决”与“阻塞”
    异步I/O
    Unix下五种IO模型
    【设计模式
    【设计模式
    【设计模式
    【设计模式
    【设计模式
    【设计模式
  • 原文地址:https://www.cnblogs.com/Blackops/p/7493464.html
Copyright © 2020-2023  润新知