zoukankan      html  css  js  c++  java
  • bzoj 4571: [Scoi2016]美味 (主席树)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4571

    题面;

    4571: [Scoi2016]美味

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 1089  Solved: 633
    [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
     
     
    思路:
    对b逐位分析,根据当前位找到能使其当前位异或为1的数的范围,在主席树中查找这个范围内是否存在数字。
    如  b第4位为1.那么要使第四位异或为1,范围就是  xxx0000 到 xxx0999
     
    实现代码;
    #include<bits/stdc++.h>
    using namespace std;
    const int M = 2e5+10;
    int ls[M*40],rs[M*40],sum[M*40],idx,rt[M];
    void update(int old,int &k,int p,int c,int l,int r){
        k = ++idx;
        ls[k] = ls[old]; rs[k] = rs[old];
        sum[k] = sum[old] + c;
        if(l == r) return ;
        int mid = (l + r) >> 1;
        if(p <= mid) update(ls[old],ls[k],p,c,l,mid);
        else update(rs[old],rs[k],p,c,mid+1,r);
    }
    
    int query(int old,int k,int L,int R,int l,int r){
        if(L <= l&&R >= r){
            return sum[k] - sum[old];
        }
        int mid = (l + r) >> 1;
        int ret = 0;
        if(L <= mid) ret += query(ls[old],ls[k],L,R,l,mid);
        if(R > mid) ret += query(rs[old],rs[k],L,R,mid+1,r);
        return ret;
    }
    
    int main()
    {
        int n,m,b,l,r,x;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i ++) cin>>x,update(rt[i-1],rt[i],x,1,0,M);
        for(int i = 1;i <= m;i ++){
            scanf("%d%d%d%d",&b,&x,&l,&r);
            int a = 0;
            for(int j = 17;j >= 0;j --){
                if(b&(1<<j)){
                    int mn = max(0,a-x),mx = (a|(1<<j)-1)-x;
                    if(mx < 0||!query(rt[l-1],rt[r],mn,mx,0,M)) a ^= (1<<j);
                }
                else{
                    a^=(1<<j);
                    int mn = max(0,a-x),mx = (a|(1<<j)-1)-x;
                    if(mx < 0||!query(rt[l-1],rt[r],mn,mx,0,M)) a^= (1<<j);
                }
            }
            printf("%d
    ",a^b);
        }
    }
  • 相关阅读:
    css基础
    html常用标签
    自写一个ant-design-pro AnimationList组件
    设计一个A表数据抽取到B表的抽取过程
    垂直、水平方向观看楼层天际线不变情况下能增加的建筑物高度最大总和
    JavaScript 新旧替换一:变量声明
    前端异常类型及捕获方式
    自定义 create-react-app
    Git Commit 规范参考
    JavaScript 团队规范参考
  • 原文地址:https://www.cnblogs.com/kls123/p/10755772.html
Copyright © 2011-2022 走看看