BOJ 487 xor

来源:互联网 发布:js取数组最后一个元素 编辑:程序博客网 时间:2024/05/16 11:37

时间限制 5000 ms 内存限制 65536 KB

题目描述

Given a sequence A1,A2,,AN, you're required to answer the following queries: given three integers l,r and x, find out max{aix}, where lir, and ab indicates the bitwise XOR(xor) operation.

输入格式

An integer T(T10) will exist in the first line of input, indicating the number of test cases. Each test case begins with two integers Nand M(1N,M50000), which separately denotes the length of the sequence and the number of queries. The following line gives N integers from A1 to AN. The next M lines, each with three integers l,r,x(1lrN), describe all the queries. All the elements in sequence A and the queried x will be set in range [0,10000].

输出格式

Output the answer for each query, one per line.

输入样例

13 21 3 21 2 11 3 1

输出样例

23
题意:

给你一段长度为 N 的数列,再给你 M 个查询, 问在 L ~ R 区间内与 x 异或最大的值

解题思路:

首先,我们明确地知道求一段区间内异或值最大的用Trie树查询,就是以该位的非值作为最优解查询,如果没有最优解不存在,或者不满足条件,则选择次优解,即该位本身数值。

其次是区间查询,在这里采用离线查询的方式,将查询按照R的大小查询,能够保证每一次查询的都满足小于R区间。L区间则是在Trie的find中维护,Trie的val数组维护的每一个经过该点的最大角标,然后就按照最优解是否存在,最优解是否在L的右边查询。

因为个人写的是递归的find,所以需要注意最后一位的处理。(之前没有判断最后一位的最优性....但是跑随机数都是对的

#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>#define eps 1e-9#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;template<class T>inline bool read(T &n){    T x = 0, tmp = 1; char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MAXN=500010;struct Node{    int l,r,x;    int idx,ans;}a[MAXN];int num[MAXN],ans_flag=0;int n,q;struct Trie{int ch[2*MAXN][2];int v[2*MAXN];int sz;Trie(){ sz=1; }int idx(int x){ return x%2; }void insert(int x,int po){int u=0;for(int i=13;i>=0;i--){int c=idx(x>>i);//cout<<(x>>i)<<endl;if(!ch[u][c]){v[sz]=po;ch[u][c]=sz++;}v[u]=po;//            cout<<" "<<u<<" "<<sz<<" "<<v[u]<<endl;u=ch[u][c];}v[u]=po;//cout<<x<<endl;}int find(int x,int l,int po,int i){    if(i==-1&&v[po]>=l)            return v[po];        int c=idx(x>>i);//cout<<po<<" "<<i<<" "<<c<<" "<<v[po]<<endl;system("pause");        if(ch[po][!c])        {            if(v[ch[po][!c]]>=l)                return find(x,l,ch[po][!c],i-1);            else                return find(x,l,ch[po][c],i-1);        }        return find(x,l,ch[po][c],i-1);}void clear(){    sz=1;memset(ch,0,sizeof(ch));memset(v,0,sizeof(v));}};Trie s;bool cmp(Node a,Node b){    return a.r<b.r;}bool cmp1(Node a,Node b){    return a.idx<b.idx;}int main(){    int T;//    freopen("data.txt","r",stdin);    read(T);    while(T--)    {        s.clear();        read(n),read(q);        for(int i=1;i<=n;i++)            read(num[i]);        for(int i=1;i<=q;i++)        {            read(a[i].l);read(a[i].r);read(a[i].x);            a[i].idx=i;        }        sort(a+1,a+q+1,cmp);        int nr=1;        for(int i=1;i<=q;i++)        {            ans_flag=0;            for(int j=nr;j<=a[i].r;j++)                s.insert(num[j],j);            nr=a[i].r+1;            a[i].ans=a[i].x^num[s.find(a[i].x,a[i].l,0,13)];//cout<<"  "<<a[i].ans<<endl;        }        sort(a+1,a+q+1,cmp1);        for(int i=1;i<=q;i++)            printf("%d\n",a[i].ans);    }    return 0;}









0 0