DTOJ #2656. 美味(food)
【题目描述】
一家餐厅有 $ n $ 道菜,编号 $ 1 \ldots n $,大家对第 $ i $ 道菜的评价值为 $ a_i \:( 1 \leq i \leq n ) \:$。有 $ m $ 位顾客,第 $ i $ 位顾客的期望值为 $ b_i $,而他的偏好值为 $ x_i $。因此,第 $ i $ 位顾客认为第 $ j $ 道菜的美味度为 $ b_i \mathbin{\text{xor}} (a_j + x_i) $($ \text{xor} $ 表示异或运算)。
第 $ i $ 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 $ l_i $ 道到第 $ r_i $ 道中选择。请你帮助他们找出最美味的菜。
【输入格式】
第一行,两个整数,$ n, m $,表示菜品数和顾客数。
第二行,$ n $ 个整数,$ a_1, a_2, \ldots, a_n $,表示每道菜的评价值。
第三至 $ m + 2 $ 行,每行 $ 4 $ 个整数,$ b, x, l, r $,表示该位顾客的期望值,偏好值,和可以选择菜品区间。
【输出格式】
输出 $ m $ 行,每行一个整数表示该位顾客选择的最美味的菜的美味值。
【样例】
样例输入
4 4
1 2 3 4
1 4 1 4
2 3 2 3
3 2 3 3
4 1 2 4
样例输出
9
7
6
7
【数据范围与提示】
对于 $30\%$ 的数据,$ 1 \le m \le 10^3 $。
对于 $100\%$ 的数据,$ 1 \leq n \leq 2 \times 10 ^ 5, 0 \leq a_i, b_i, x_i < 10 ^ 5, 1 \leq l_i \leq r_i \leq n(1 \leq i \leq m), 1 \leq m \leq 10 ^ 5 $。
【题解】
看到异或不难想到 $Trie$ 树,然而这题跟 $Trie$ 树没啥关系(如果你硬要把值域线段树和Trie说成同一个东西这句话当我没说)。
要求的式子显然没法直接算,根据一般套路,考虑按位贪心。
记已经考虑完的位答案为 $ans$,考虑当前第 $i$ 位,如果 $b$ 的当前位为 $0$,显然如果 $a_j+x$ 这一位为 $1$ 更优。而 $a_j+x$ 的前几位一定要与 $ans$ 相同,则 $a_j+x$ 的取值范围为 $[ans+2^i,ans+2^{i+1}-1]$,可得 $a_j$ 的范围应在 $[ans+2^i-x,ans+2^{i+1}-1-x]$ 内最优。这是值域的限制。而 $l,r$ 是对位置的限制。二维限制其中一位满足可减性,用主席树维护即可。$b$ 的当前位为 $1$ 同理。
【代码】
#include<bits/stdc++.h> inline int read ( void ) { int x=0;char ch;bool f=true; while ( !isdigit(ch=getchar()) ) if ( ch=='-' ) f=false; for ( x=ch^48;isdigit(ch=getchar()); ) x=(x<<1)+(x<<3)+(ch^48); return f ? x : -x ; } int L,R,n,A[200010],tot,root[200010]; struct tree { int ls,rs,tot; } t[10000000]; inline void modify ( int &k,int fr,int l,int r,int p ) { t[k=++tot].tot=t[fr].tot+1; if ( l==r ) return; int mid=(l+r)>>1; if ( p<=mid ) modify(t[k].ls,t[fr].ls,l,mid,p),t[k].rs=t[fr].rs; else modify(t[k].rs,t[fr].rs,mid+1,r,p),t[k].ls=t[fr].ls; } inline int query ( int k1,int k2,int l,int r,int ql,int qr ) { if ( ql>qr ) return 0; if ( ql<=l and r<=qr ) return t[k1].tot-t[k2].tot; int mid=(l+r)>>1,res=0; if ( ql<=mid ) res+=query(t[k1].ls,t[k2].ls,l,mid,ql,qr); if ( qr>mid ) res+=query(t[k1].rs,t[k2].rs,mid+1,r,ql,qr); return res; } signed main() { n=read();int q=read(); for ( int i=1;i<=n;i++ ) R=std::max(R,A[i]=read()); for ( int i=1;i<=n;i++ ) modify(root[i],root[i-1],L,R,A[i]); while ( q-- ) { int b=read(),x=read(),l=read(),r=read(),ans=0; for ( int i=18;~i;i-- ) if ( b&(1<<i) ) { if ( !query(root[r],root[l-1],L,R,std::max(ans-x,L),std::min(ans+(1<<i)-1-x,R)) ) ans+=(1<<i); } else { if ( query(root[r],root[l-1],L,R,std::max(ans+(1<<i)-x,L),std::min(ans+(1<<(i+1))-1-x,R)) ) ans+=(1<<i); } printf("%d\n",ans^b); } return 0; }
原文地址:https://www.cnblogs.com/RenSheYu/p/11311574.html
- JS魔法堂: Native Promise Only源码剖析
- JavaWeb(三)JSP概述
- 人工智能拥有意识,仅是一个时间问题而已
- sqlserver 配置c3p0 连接池
- spring mvc 返回图片的请求
- JavaWeb(二)cookie与session的应用
- JS魔法堂:函数重载 之 获取变量的数据类型
- 开发问题(一)在windows和linux端口占用问题
- Linux文件系统的实现
- Design Pattern: Not Just Mixin Pattern
- 关于PHP字符编码的函数区别
- Java集合源码分析(二)Linkedlist
- array_shift() 函数
- 可穿戴设备:不要纠结“可穿戴”
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- WPF加载中实现
- Chrome Headless 尝试
- MySQL--索引及优化查询
- Nginx 配置相关--Gzip压缩、CORS
- Webpack+Vue2项目结构生成
- 关于跨域以及Spring Boot的解决方案
- FFmpeg进行音频的解码和播放
- Gitbook 安装及使用
- MySQL 视图、过程、函数
- 基于Spring Boot + Dubbo的全链路日志追踪(二)
- 基于Spring Boot + Dubbo的全链路日志追踪(一)
- 使用C语言编写Python扩展包
- PlantUML基本使用(一)--时序图
- gRPC基本使用(一)--java与go之间的相互调用
- confd基本使用--Nginx配置自动化