时间限制 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{ai⊕x} , where l≤i≤r , and a⊕b indicates the bitwise XOR(xor) operation.输入格式
An integer T(T≤10) will exist in the first line of input, indicating the number of test cases. Each test case begins with two integers N and M(1≤N,M≤50000) , 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(1≤l≤r≤N) , 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.输入样例
1
3 2
1 3 2
1 2 1
1 3 1
输出样例
2
3
给你一段长度为 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 0x3f3f3f3f
using 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;
}