给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R)。求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?Input第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000)。
第2 - N+1行:每行1个数,对应数组A的元素(0 <= Aii <= 10^9)。
第N+2 - N+Q+1行:每行3个数X, L, R,中间用空格分隔。(0 <= X <= 10^9,0 <= L <= R < N)Output输出共Q行,对应数组A的区间L,RL,R中的数与X进行异或运算,所能得到的最大值。Sample 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
Sample Output
13 1016 41 191 191 15 107 47
懒得说了。反正主席树写习惯了,持久化Trie也就直接写了。
#include<bits/stdc++.h> using namespace std; const int maxn=100010; int a[maxn],rt[maxn],cnt; struct node{ int l,r,val; node(){ l=r=val=0; } node(int L,int R,int V):l(L),r(R),val(V){} }s[maxn*20]; void add(int &now,int pre,int x,int pos) { now=++cnt; s[now]=node(s[pre].l,s[pre].r,s[pre].val+1); if(pos==-1) return ; if(((x>>pos)%2)==0) add(s[now].l,s[pre].l,x,pos-1); else add(s[now].r,s[pre].r,x,pos-1); } int query(int now,int pre,int x) { int res=0; for(int i=30;i>=0;i--){ int t=(x>>i)%2; if(t==0){ if(s[now].r&&s[s[now].r].val-s[s[pre].r].val>0) now=s[now].r, pre=s[pre].r, res+=(1<<i); else now=s[now].l, pre=s[pre].l; } if(t==1){ if(s[now].l&&s[s[now].l].val-s[s[pre].l].val>0) now=s[now].l, pre=s[pre].l, res+=(1<<i); else now=s[now].r, pre=s[pre].r; } } return res; } int main() { int N,Q,L,R,x,i; scanf("%d%d",&N,&Q); for(i=1;i<=N;i++){ scanf("%d",&a[i]); add(rt[i],rt[i-1],a[i],30); } for(i=1;i<=Q;i++){ scanf("%d%d%d",&x,&L,&R); int ans=query(rt[R+1],rt[L],x); printf("%d\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/hua-dong/p/9126937.html
时间: 2024-10-10 04:16:28