zoukankan      html  css  js  c++  java
  • [TJOI 2018] XOR

    [题目链接]

           https://www.lydsy.com/JudgeOnline/problem.php?id=5338

    [算法]

            首先对这棵树进行树链剖分

            那么我们就将一个树上的问题转化为一个序列上的问题

            建立可持久化字典树维护最大异或值即可

            时间复杂度 : O(NlogN ^ 2)

    [代码]

           

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 2e5 + 10;
    const int MAXLOG = 31;
    
    struct edge
    {
            int to , nxt;
    } e[N << 1];
    
    int n , tot , timer , q;
    int head[N] , size[N] , top[N] , a[N] , perm[N] , l[N] , r[N] , son[N] , father[N] , depth[N] , rt[N];
    
    struct Presitent_Trie
    {
            int sz;
            int child[N * MAXLOG][2] , latest[N * MAXLOG];
            Presitent_Trie()
            {
                    sz = 0;        
            }        
            inline void modify(int bit , int &now , int old , int x , int loc)
            {
                    now = ++sz;
                    child[now][0] = child[old][0] , child[now][1] = child[old][1];
                    latest[now] = loc;
                    if (bit < 0) return;
                    int value = 0;
                    if (x & (1 << bit)) value = 1;
                    modify(bit - 1 , child[now][value] , child[old][value] , x , loc);
            }
            inline int query(int bit , int now , int lft , int x)
            {
                    if (bit < 0)
                            return 0;
                    int value = 1;
                    if (x & (1 << bit)) value = 0;
                    if (latest[child[now][value]] >= lft) return (1 << bit) + query(bit - 1 , child[now][value] , lft , x);
                    else return query(bit - 1 , child[now][value ^ 1] , lft , x);
            }
    } PT;
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u , int v)
    {
            ++tot;
            e[tot] = (edge){v , head[u]};
            head[u] = tot;
    }
    inline void dfs1(int u , int par)
    {
            size[u] = 1;
            depth[u] = depth[par] + 1;
            father[u] = par;
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to;
                    if (v == par) continue;
                    dfs1(v , u);
                    size[u] += size[v];
                    if (size[v] > size[son[u]]) son[u] = v;
            }        
    }
    inline void dfs2(int u , int t)
    {
            top[u] = t;
            l[u] = ++timer;
            if (son[u]) dfs2(son[u] , t);
            for (int i = head[u]; i; i = e[i].nxt)        
            {
                    int v = e[i].to;
                    if (v == father[u] || v == son[u]) continue;
                    dfs2(v , v);
            }
            r[u] = timer;
    }
    inline bool cmp(int x , int y)
    {
            return l[x] < l[y];
    } 
    inline int query(int x , int y , int z)
    {    
            int ans = 0;
            while (top[x] != top[y])
            {
                    if (depth[top[x]] > depth[top[y]]) swap(x , y);
                    chkmax(ans , PT.query(MAXLOG - 1 , rt[l[y]] , l[top[y]] , z));
                    y = father[top[y]];
            }
            if (depth[x] > depth[y]) swap(x , y);
            chkmax(ans , PT.query(MAXLOG - 1 , rt[l[y]] , l[x] , z));
            return ans;
    }
    
    int main()
    {
            
            read(n); read(q);
            for (int i = 1; i <= n; ++i) read(a[i]);
            for (int i = 1; i < n; ++i)
            {
                    int x , y;
                    read(x); read(y);
                    addedge(x , y);
                    addedge(y , x);
            }
            dfs1(1 , 0);
            dfs2(1 , 1);
            for (int i = 1; i <= n; ++i) perm[i] = i;
            sort(perm + 1 , perm + n + 1 , cmp);
            for (int i = 1; i <= n; ++i) PT.modify(MAXLOG - 1 , rt[i] , rt[i - 1] , a[perm[i]] , i); 
            while (q--) 
            {
                    int type;
                    read(type);
                    if (type == 1)
                    {
                            int x , y;
                            read(x); read(y);
                            printf("%d
    " , PT.query(MAXLOG - 1 , rt[r[x]] , l[x] , y));        
                    }    else
                    {
                            int x , y , z;
                            read(x); read(y); read(z);
                            printf("%d
    " , query(x , y , z));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    领扣(LeetCode)七进制数 个人题解
    ie固定table单元格宽度
    js 阻止冒泡
    在jsp页面下, 让eclipse完全支持HTML/JS/CSS智能提示(转)
    WebStorm 6.0 与 7.0 注册码
    统制Highcharts中x轴和y轴坐标值的密度
    ie版本
    flash透明 处于最低
    eclipse svn --
    jquery---- 数组根据值进行删除
  • 原文地址:https://www.cnblogs.com/evenbao/p/10540007.html
Copyright © 2011-2022 走看看