1. 程式人生 > >[BZOJ4571][Scoi2016]美味 貪心+主席樹

[BZOJ4571][Scoi2016]美味 貪心+主席樹

ref opened www. sin 技術 sta hide ont sub

4571: [Scoi2016]美味

Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 751 Solved: 410
[Submit][Status][Discuss]

Description

一家餐廳有 n 道菜,編號 1...n ,大家對第 i 道菜的評價值為 ai(1≤i≤n)。有 m 位顧客,第 i 位顧客的期 望值為 bi,而他的偏好值為 xi 。因此,第 i 位顧客認為第 j 道菜的美味度為 bi XOR (aj+xi),XOR 表示異或 運算。第 i 位顧客希望從這些菜中挑出他認為最美味的菜,即美味值最大的菜,但由於價格等因素,他只能從第 li 道到第 ri 道中選擇。請你幫助他們找出最美味的菜。

Input

第1行,兩個整數,n,m,表示菜品數和顧客數。 第2行,n個整數,a1,a2,...,an,表示每道菜的評價值。 第3至m+2行,每行4個整數,b,x,l,r,表示該位顧客的期望值,偏好值,和可以選擇菜品區間。 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 ,表示該位顧客選擇的最美味的菜的美味值。

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

HINT

Source

建立主席樹。

按位貪心,由於高位確定,查詢當前位為1/0的範圍內是否有數。

技術分享圖片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define maxn 200005
 8 #define ls(x) t[x].s[0]
 9 #define rs(x) t[x].s[1]
10 using namespace
std; 11 struct data { 12 int s[2],sz; 13 }t[maxn*20]; 14 int cnt; 15 void insert(int pre,int &now,int l,int r,int x) { 16 now=++cnt; 17 t[now]=t[pre]; 18 t[now].sz++; 19 if(l==r) return; 20 int mid=l+r>>1; 21 if(x<=mid) insert(ls(pre),ls(now),l,mid,x); 22 else insert(rs(pre),rs(now),mid+1,r,x); 23 } 24 int query(int pre,int now,int l,int r,int L,int R) { 25 if(L<=l&&R>=r) return t[now].sz-t[pre].sz; 26 int mid=l+r>>1; 27 int re=0; 28 if(L<=mid) re+=query(ls(pre),ls(now),l,mid,L,R); 29 if(R>mid) re+=query(rs(pre),rs(now),mid+1,r,L,R); 30 return re; 31 } 32 int root[maxn]; 33 int n,m; 34 int main() { 35 scanf("%d%d",&n,&m); 36 for(int i=1;i<=n;i++) {int x;scanf("%d",&x);insert(root[i-1],root[i],1,maxn,x);} 37 for(int i=1;i<=m;i++) { 38 int b,x,l,r; 39 scanf("%d%d%d%d",&b,&x,&l,&r); 40 int ans=0; 41 for(int j=17;j>=0;j--) { 42 if((b>>j)&1) { 43 int L=max(0,ans-x),R=ans+(1<<j)-1-x; 44 if(R<0||!query(root[l-1],root[r],1,maxn,L,R)) ans+=(1<<j); 45 } 46 else { 47 int L=max(0,ans+(1<<j)-x),R=ans+(1<<(j+1))-1-x; 48 if(query(root[l-1],root[r],1,maxn,L,R)) ans+=(1<<j); 49 } 50 } 51 printf("%d\n",ans^b); 52 } 53 }
View Code

[BZOJ4571][Scoi2016]美味 貪心+主席樹