• 【bzoj4571 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 ,表示该位顾客选择的最美味的菜的美味值。

    题意:
    n个数,m个询问,每个询问要求输出l-r区间内(ai+x) xor b的最大值;

     ①一个数异或多个数异或最大值,还是可以考虑可持久化字典树

    ②但是有偏好值,让可持久话字典树变成字典树套主席树,构造到第j位,已经确定好的j位以上的答案(ai+x)是ans,每次在ans^(~b&(1<<j)) 到 ans^(~b&(1<<j)) + (1<<j)-1区间里查询是否有值。

     

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 const int N = 200010,S = 20,M = 100000;
     5 int n,m,sz,a[N],rt[N],ls[N*S],rs[N*S],sum[N*S],bin[S];
     6 char gc(){
     7     static char *p1,*p2,s[1000000];
     8     if(p1==p2) p2=(p1=s)+fread(s,1,1000000,stdin);
     9     return(p1==p2)?EOF:*p1++;
    10 }
    11 int rd(){
    12     int x = 0,f = 1; char c = gc();
    13     while(c<'0'||c>'9') {if(c=='-') f = -1; c = gc();}
    14     while(c>='0'&&c<='9') x=x*10+c-'0',c = gc();
    15     return x * f;
    16 }
    17 void ins(int &k,int last,int l,int r,int x){
    18     k = ++sz; 
    19     sum[k] = sum[last] + 1,ls[k] = ls[last],rs[k] = rs[last];
    20     if(l==r) return ;
    21     int mid = (l+r)>>1;
    22     if(x<=mid) ins(ls[k],ls[last],l,mid,x);
    23     else ins(rs[k],rs[last],mid+1,r,x);
    24 }
    25 bool query(int k1,int k2,int l,int r,int ql,int qr){
    26     if(l==ql&&qr==r){
    27         return bool(sum[k2]-sum[k1]);
    28     }
    29     else {
    30         int mid = (l+r)>>1;
    31         if(qr<=mid) return query(ls[k1],ls[k2],l,mid,ql,qr);
    32         else if(ql>mid) return query(rs[k1],rs[k2],mid+1,r,ql,qr);
    33         else return query(ls[k1],ls[k2],l,mid,ql,mid)|query(rs[k1],rs[k2],mid+1,r,mid+1,qr);
    34     }
    35 }
    36 int main()
    37 {    freopen("bzoj4571.in","r",stdin);
    38     freopen("bzoj4571.out","w",stdout);
    39     n  = rd(); m = rd();
    40     for(int i = 1;i <= n;i++) ins(rt[i],rt[i-1],0,M,a[i] = rd());
    41     for(int i = bin[0] = 1;i <= 17;i++) bin[i] = bin[i-1]<<1;
    42     for(int i = 1,l,r,b,x;i <= m;i++){
    43         b = rd(); x = rd(); l = rd(); r = rd();
    44         int ans = 0;
    45         for(int k = 17;k>=0;k--){
    46             if(!((b>>k)&1)) ans |= bin[k];
    47             int L = max(0,ans - x),R = min((ans|(bin[k]-1)) - x,M); 
    48             if(L > M || R < 0 || !query(rt[r],rt[l-1],0,M,L,R)) ans ^= bin[k];
    49         }
    50         printf("%d
    ",ans^b);
    51     }
    52     return 0;
    53 }//by tkys_Austin;

     

     

  • 相关阅读:
    git的冲突解决--git rebase之abort、continue、skip
    iOS 13苹果登录
    mac上python3.x安装 图文详解
    iOS Bezier曲线
    《从零开始学Swift》学习笔记(Day 23)——尾随闭包
    《从零开始学Swift》学习笔记(Day 22)——闭包那些事儿!
    《从零开始学Swift》学习笔记(Day 21)——函数返回值
    《从零开始学Swift》学习笔记(Day 20)——函数中参数的传递引用
    《从零开始学Swift》学习笔记(Day 19)——函数参数传递
    《从零开始学Swift》学习笔记(Day 18)——有几个分支语句?
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/8648444.html
Copyright © 2020-2023  润新知