zoukankan      html  css  js  c++  java
  • 51nod 1295 XOR key (可持久化Trie树)

    题目来源: HackerRank
    基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题
     
    给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R)。求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?
    Input
    第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000)。
    第2 - N+1行:每行1个数,对应数组A的元素(0 <= A[i] <= 10^9)。
    第N+2 - N+Q+1行:每行3个数X, L, R,中间用空格分隔。(0 <= X <= 10^9,0 <= L <= R < N)
    Output
    输出共Q行,对应数组A的区间[L,R]中的数与X进行异或运算,所能得到的最大值。
    Input示例
    15 8  
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    10 5 9
    1023 6 6
    33 4 7
    182 4 9
    181 0 12
    5 9 14
    99 7 8
    33 9 13
    Output示例
    13  
    1016  
    41  
    191  
    191  
    15  
    107  
    47

    思路:
    可持久化Trie树模板题,不加输入输出是优化也可以过,加了会减很多耗时,之前数组开小了,超时了好几发。
    参考博客:
    https://www.cnblogs.com/RabbitHu/p/51nod1295.html
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int M = 1e5+10;
    int a[M];
    int rt[M]={1},siz[M<<5],son[M<<5][2],idx;
    template <class T>
    void read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x){
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    void Insert(int i,int x){
         int now = rt[i] = ++idx;
         int old = rt[i-1];
         for(int i = 31;i >= 0;i --){
            siz[now] = siz[old] + 1;
            if((x >> i)& 1) son[now][0] = son[old][0],son[now][1] = ++idx;
            else son[now][1] = son[old][1],son[now][0] = ++idx;
            now = son[now][(x>>i)&1];
            old = son[old][(x>>i)&1];
         }
         siz[now] = siz[old] + 1;
    }
    
    int query(int l,int r,int x){
        int now = rt[r],old = rt[l],ans = 0;
        for(int i = 31;i >= 0;i --){
            int dir = (x >> i)&1;
            int delta_siz = siz[son[now][!dir]] - siz[son[old][!dir]];
            if(delta_siz) now = son[now][!dir],old = son[old][!dir],ans = ans <<1 |1;
            else now = son[now][dir],old = son[old][dir],ans = ans << 1;
        }
        return ans;
    }
    
    int main(){
        int n,q,l,r,x;
        idx = 1;
        read(n);read(q);
        for(int i = 1;i <= n;i ++){
            read(a[i]);
        }
        for(int i = 1;i <= n;i ++)
            Insert(i,a[i]);
        while(q--){
            read(x);read(l);read(r);
            write(query(l,r+1,x));
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    hashCode花式卖萌
    2017年的小总结
    多线程环境下的单例模式
    Servlet过滤器简单探索
    最长回文子序列(LPS)
    最短编辑距离问题
    赫夫曼编码
    DNA序列对齐问题
    同时寻找序列的最大最小值
    最长公共子序列(LCS)
  • 原文地址:https://www.cnblogs.com/kls123/p/9107861.html
Copyright © 2011-2022 走看看