• bzoj [Scoi2016]美味


     [Scoi2016]美味

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 721  Solved: 391
    [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

    题解:

    区间最大异或值的经典做法是可持久化trie,但是加上一个数的话可持久化trie就变得非常的扯淡

    考虑可持久化trie其实可以等价为一颗上限为2^k-1的主席树,在trie上确定一位其实相当于将答案的区间缩小的一半,也就是在主席树上向下走一层

    当所有数加上x之后,我们在主席树上走的时候就不能直接调用siz[son[x][0]],但是因为所有数都被加了,所以我们其实要查询的是左子树的区间向前窜x位之后的区间有没有数,这样的话每次走的时候在主席树上重新查[l-x,mid-x]或者[mid+1-x,r-x]来判断应该往哪边走即可,复杂度多了个log,但是n=2*10^5,不虚

    然后就过了

    时间复杂度O(m log^2 n)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 const int N=1<<18;
     6 const int maxn=200010;
     7 int n,m,tot;
     8 int rt[maxn];
     9 struct node
    10 {
    11     int ls,rs,siz;
    12 }s[maxn*30];
    13 void insert(int x,int &y,int l,int r,int a)
    14 {
    15     y=++tot,s[y].siz=s[x].siz+1;
    16     if(l==r)    return ;
    17     int mid=(l+r)>>1;
    18     if(a<=mid)   s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,a);
    19     else    s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,a);
    20 }
    21 int query(int l,int r,int x,int y,int a,int b)
    22 {
    23     if(a<=l&&r<=b)    return s[x].siz-s[y].siz;
    24     int mid=(l+r)>>1;
    25     if(b<=mid)   return query(l,mid,s[x].ls,s[y].ls,a,b);
    26     if(a>mid)    return query(mid+1,r,s[x].rs,s[y].rs,a,b);
    27     return query(l,mid,s[x].ls,s[y].ls,a,b)+query(mid+1,r,s[x].rs,s[y].rs,a,b);
    28 }
    29 inline int find(int l,int r,int a,int b)
    30 {
    31     int i,j=0,d;
    32     for(i=1<<18;i;i>>=1)
    33     {
    34         d=(b&i)>0;
    35         if(d&&!query(0,N,rt[r],rt[l-1],j-a,j+i-a-1))    j+=i;
    36         if(!d&&query(0,N,rt[r],rt[l-1],j+i-a,j+i+i-a-1))    j+=i;
    37     }
    38     return b^j;
    39 }
    40 inline int rd()
    41 {
    42     int ret=0,f=1;  char gc=getchar();
    43     while(gc<'0'||gc>'9') {if(gc=='-')    f=-f;   gc=getchar();}
    44     while(gc>='0'&&gc<='9')   ret=ret*10+gc-'0',gc=getchar();
    45     return ret*f;
    46 }
    47 int main()
    48 {
    49     int i,a,b,c,d;
    50     n=rd(),m=rd();
    51     for(i=1;i<=n;i++)  
    52         a=rd(),insert(rt[i-1],rt[i],0,N,a);
    53     for(i=1;i<=m;i++)
    54     {
    55         a=rd(),b=rd(),c=rd(),d=rd();
    56         printf("%d
    ",find(c,d,b,a));
    57     }
    58 }
  • 相关阅读:
    线程池的项目参考
    一文了解模型量化中的QAT和PTQ
    cookie 、 session、token分别是什么
    Browser storage limits and eviction criteria
    PropertyGridControl for dynamic properties
    Chrome 允许浏览器使用多达 80% 的总磁盘空间。一个来源最多可以使用总磁盘空间的 60%。
    Windbg查看调用堆栈(k*)
    ToDoList是一款非常实用的任务管理软件
    Windbg调试Unity3d 卡死 无响应等问题测试
    加密国密非对称SM2
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8142777.html
Copyright © 2020-2023  润新知