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('\n');
    }
    return 0;
}

 

posted @ 2018-05-29 20:54  冥想选手  阅读(145)  评论(0编辑  收藏  举报