# 【BZOJ4571】[Scoi2016]美味

## Input

1≤n≤2×10^5，0≤ai,bi,xi＜10^5，1≤li≤ri≤n(1≤i≤m)；1≤m≤10^5

## Output

输出 m 行，每行 1 个整数，ymax ，表示该位顾客选择的最美味的菜的美味值。

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

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N=1<<18;
const int maxn=200010;
int n,m,tot;
int rt[maxn];
struct node
{
int ls,rs,siz;
}s[maxn*30];
void insert(int x,int &y,int l,int r,int a)
{
y=++tot,s[y].siz=s[x].siz+1;
if(l==r)	return ;
int mid=(l+r)>>1;
if(a<=mid)	s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,a);
else	s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,a);
}
int query(int l,int r,int x,int y,int a,int b)
{
if(a<=l&&r<=b)	return s[x].siz-s[y].siz;
int mid=(l+r)>>1;
if(b<=mid)	return query(l,mid,s[x].ls,s[y].ls,a,b);
if(a>mid)	return query(mid+1,r,s[x].rs,s[y].rs,a,b);
return query(l,mid,s[x].ls,s[y].ls,a,b)+query(mid+1,r,s[x].rs,s[y].rs,a,b);
}
inline int find(int l,int r,int a,int b)
{
int i,j=0,d;
for(i=1<<18;i;i>>=1)
{
d=(b&i)>0;
if(d&&!query(0,N,rt[r],rt[l-1],j-a,j+i-a-1))	j+=i;
if(!d&&query(0,N,rt[r],rt[l-1],j+i-a,j+i+i-a-1))	j+=i;
}
return b^j;
}
inline int rd()
{
int ret=0,f=1;	char gc=getchar();
while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
int i,a,b,c,d;
n=rd(),m=rd();
for(i=1;i<=n;i++)	a=rd(),insert(rt[i-1],rt[i],0,N,a);
for(i=1;i<=m;i++)
{
a=rd(),b=rd(),c=rd(),d=rd();
printf("%d\n",find(c,d,b,a));
}
return 0;
}//4 4  1 2 3 4  1 4 1 4  2 3 2 3  3 2 3 3  4 1 2 4
posted @ 2017-10-15 11:40  CQzhangyu  阅读(192)  评论(0编辑  收藏  举报