51nod 1295 XOR key(字典树)

来源:互联网 发布:网站结构优化 编辑:程序博客网 时间:2024/05/17 06:33

1295 XOR key
题目来源: 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  12345678910111213141510 5 91023 6 633 4 7182 4 9181 0 125 9 1499 7 833 9 13
Output示例
13  1016  41  191  191  15  107  47


本来以为会超时,没想到竟然水过去了



#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<map>#include <bits/stdc++.h>using namespace std;const int N = 50000+10;typedef long long LL;typedef pair<int,int> pi;vector<int>p[N*30];int rt[N*30][2], cnt;LL ans;void insert1(LL x,int id){    int root=0;    for(int i=30;i>=0;i--)    {        int v=((x&(1<<i))?1:0);        if(rt[root][v]==-1)        {            rt[root][v]=cnt;            rt[cnt][0]=rt[cnt][1]=-1;            cnt++;        }        root=rt[root][v];        p[root].push_back(id);    }    return ;}void get(LL x,int l,int r){    int root=0;    for(int i=30;i>=0;i--)    {        int v=((x&(1<<i))?1:0);        if(rt[root][1^v]!=-1)        {            int y=rt[root][1^v];            int pos=lower_bound(p[y].begin(),p[y].end(),l)-p[y].begin();            if(pos!=p[y].size()&&p[y][pos]>=l&&p[y][pos]<=r)            {                ans|=(1<<i);                root=y;                continue;            }        }        if(rt[root][v]!=-1)        {            int y=rt[root][v];            if(v==1) ans^=(1<<i);            root=y;        }    }    return ;}int main(){    int n, m;    LL x;    scanf("%d %d", &n, &m);    rt[0][0]=rt[0][1]=-1;    cnt=1;    for(int i=0;i<n;i++)    {        scanf("%lld", &x);        insert1(x,i);    }    while(m--)    {        int l, r;        scanf("%lld %d %d", &x, &l, &r);        ans=x;        get(x, l, r);        printf("%lld\n",ans);    }    return 0;}








原创粉丝点击