Description
一家餐厅有(n)道菜,编号(1...n),大家对第(i)道菜的评价值为(a_i(1≤i≤n))。有(m)位顾客,第(i)位顾客的期望值为(b_i),而他的偏好值为(x_i) 。因此,第(i)位顾客认为第(j)道菜的美味度为(b_i XOR (a_j+x_i)),(XOR) 表示异或运算。第(i)位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 (l_i)道到第(r_i)道中选择。请你帮助他们找出最美味的菜。
Input
第1行,两个整数(n),(m),表示菜品数和顾客数。
第2行,(n)个整数,(a_1),(a_2),(...),(a_n),表示每道菜的评价值。
第3至(m+2)行,每行4个整数(b,x,l,r,)表示该位顾客的期望值,偏好值,和可以选择菜品区间。
$ 1≤n≤2×10^5,0≤a_i,b_i,x_i<10^5,1≤l_i≤r_i≤n(1≤i≤m);1≤m≤10^5$
Output
输出(m)行,每行 1 个整数,(ymax),表示该位顾客选择的最美味的菜的美味值。
Sample Input
4 4
1 2 3 4
1 4 1 4
2 3 2 3
3 2 3 3
4 1 2 4
Sample Output
9
7
6
7
题解
首先在区间([l,r])里面选就肯定是主席树了吧。
然后既然求异或结果最大那么就考虑按位贪心。
设(ans=a_j+x_i),那么我们就希望(ans)在二进制上从高位到低位尽量都与(b_i)不同。我们假设不同,那么就是确定了某一个最高位的数值。假设确定的是第(i)位的数值,那么我们相当于确定了解的范围,即一个长度为(2^i)的区间。接下来就是通过两棵主席树作差找这个范围内是否存在解了。
code
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 200005;
struct president_tree{int ls,rs,num;}t[N*25];
int n,m,a,rt[N],tot,b,x,l,r,L,R,ans,opt;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
void build(int &now,int l,int r)
{
now=++tot;
if (l==r) return;
int mid=l+r>>1;
build(t[now].ls,l,mid);
build(t[now].rs,mid+1,r);
}
void update(int &now,int l,int r,int pos)
{
t[++tot]=t[now];
t[now=tot].num++;
if (l==r) return;
int mid=l+r>>1;
if (pos<=mid) update(t[now].ls,l,mid,pos);
else update(t[now].rs,mid+1,r,pos);
}
int Query(int A,int B,int l,int r,int ql,int qr)
{
if (l>=ql&&r<=qr) return t[A].num-t[B].num;
int mid=l+r>>1,s=0;
if (ql<=mid) s+=Query(t[A].ls,t[B].ls,l,mid,ql,qr);
if (qr>mid) s+=Query(t[A].rs,t[B].rs,mid+1,r,ql,qr);
return s;
}
int main()
{
n=gi();m=gi();
build(rt[0],1,N);
for (int i=1;i<=n;i++)
{
a=gi();
rt[i]=rt[i-1];
update(rt[i],0,N,a);
}
while (m--)
{
b=gi();x=gi();l=gi();r=gi();ans=0;
for (int i=17;i>=0;i--)
{
if (b&(1<<i)) L=ans,R=ans+(1<<i)-1,opt=0;
else L=ans+(1<<i),R=ans+(1<<i+1)-1,opt=1;
if (!Query(rt[r],rt[l-1],0,N,max(0,L-x),min(N,R-x))) opt^=1;
ans|=opt<<i;
}
printf("%d
",ans^b);
}
return 0;
}