• [SCOI2016]美味


    题目描述

    一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n)。有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi 。因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异或运算。

    第 i 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 li 道到第 ri 道中选择。请你帮助他们找出最美味的菜。

    输入输出格式

    输入格式:

    第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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    4 4
    1 2 3 4
    1 4 1 4
    2 3 2 3
    3 2 3 3
    4 1 2 4
    输出样例#1: 复制
    9 
    7 
    6 
    7
    用主席树维护1~r内节点代表区间的值有多少个
    我们求出使b^ans最大的ans
    首先考虑贪心,即匹配到了第i位,那么第i+1位能要就要
    从一位i开始,b这一位假设是1
    那么看l~r之间有无使b第i位为1的,因为贪心,所以我们尽可能使i位为1就行,前i-1位可以不管
    显然我们已经处理了前i-1位了,设当前结果是ans
    所以我们要查询的范围为[ans-x,ans+(1<<i)-1-x]
    查询范围+ans是为了贪心满足前面的位的情况下才算

    右端的意思是后面的位由于贪心不管
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int pos,root[200001],ch[5000001][2],sum[5000001],n,m,a[200001];
     7 void update(int &rt,int l,int r,int x)
     8 {
     9   int Rt=rt;
    10   rt=++pos;
    11   ch[rt][0]=ch[Rt][0];ch[rt][1]=ch[Rt][1];
    12   sum[rt]=sum[Rt]+1;
    13   if (l==r) return;
    14   int mid=(l+r)/2;
    15   if (x<=mid) update(ch[rt][0],l,mid,x);
    16   else update(ch[rt][1],mid+1,r,x);
    17 }
    18 int query(int rt1,int rt2,int l,int r,int L,int R)
    19 {
    20   if (l>=L&&r<=R)
    21     return sum[rt2]-sum[rt1];
    22   int mid=(l+r)/2,s=0;
    23   if (L<=mid) s+=query(ch[rt1][0],ch[rt2][0],l,mid,L,R);
    24   if (R>mid) s+=query(ch[rt1][1],ch[rt2][1],mid+1,r,L,R);
    25   return s;
    26 }
    27 bool find(int i,int j,int l,int r)
    28 {
    29   if (l<0) l=0;
    30   if (r>100000) r=100000;
    31   if (l>r) return 0;
    32   if (query(root[i],root[j],0,100000,l,r)) return 1;
    33   return 0;
    34 }
    35 int main()
    36 {int i,b,x,l,r,j;
    37   cin>>n>>m;
    38   for (i=1;i<=n;i++)
    39     {
    40       scanf("%d",&a[i]);
    41       root[i]=root[i-1];
    42       update(root[i],0,100000,a[i]);
    43     }
    44   for (i=1;i<=m;i++)
    45     {
    46       scanf("%d%d%d%d",&b,&x,&l,&r);
    47       int ans=0;
    48       for (j=17;j>=0;j--)
    49     {
    50       int now=ans+((1^((b>>j)&1))<<j);
    51       if (find(l-1,r,now-x,now+(1<<j)-1-x)) ans=now;
    52       else ans+=(((b>>j)&1)<<j);
    53     }
    54       printf("%d
    ",ans^b);
    55     }
    56 }
  • 相关阅读:
    Object.assign()方法
    JavaScript对象(二)
    JavaScript对象(一)
    vue开发中遇到的问题集锦(2)
    Python:str.ljust()、str.rjust()、str.center()函数
    Python:如何将多个小字符串拼接成一个大的字符串
    Python:.join()函数
    Python:生成器表达式
    VS Code:快捷方式
    Python:如何调整字符串中文本的格式
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8240954.html
Copyright © 2020-2023  润新知