「SCOI2016」美味

题目描述

一家餐厅有 \(n\) 道菜,编号 \(1 \ldots n\) ,大家对第 \(i\) 道菜的评价值为 \(a_i \:( 1 \leq i \leq n )\)。有 \(m\) 位顾客,第 \(i\) 位顾客的期望值为 \(b_i\),而他的偏好值为 \(x_i\)。因此,第 \(i\) 位顾客认为第 \(j\) 道菜的美味度为 \(b_i\ \text{xor} \ (a_j+x_i)\) (\(\text{xor}\) 表示异或运算)。 第 \(i\) 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 \(l_i\) 道到第 \(r_i\) 道中选择。请你帮助他们找出最美味的菜。

解题思路 :

问题要求从区间里找一个数 \(a_j\) ,使得 \((a_j + x_i) \text{ xor } b_i\) 最大,先考虑当 \(x_i = 0\) 的时候是一个经典问题该怎么做

当 \(x_i = 0\) 时显然直接用一个可持久化 \(Trie\) 树按位维护区间内所有 \(a_j\) 查询即可

但是有加上 \(x_i\) 的操作由于 \(Trie\) 的局限性就不那么可做了,不妨考虑上述算法的本质

\(Trie\) 树从高到低走的每一位本质上是对最终选的数的可行区间不断减少

设当前第 \(i\) 位的大小是 \(2^i\) ,那么如果选了它答案一定 $ \geq 2^i$ ,否则答案一定 \(< 2 ^i\) ,因为有 \(\sum_{j=0}^{i-1} 2^j =2^i - 1\)

所以我们可以用一个线段树维护 \([0, 2^{lim-1}]\) 的权值来代替原本的 \(Trie\),每次走左儿子本质上是这一位选了 \(0\),走右儿子本质上是选了 \(1\)

考虑查询加上 \(x_i\) 后的 \(a_j\) 本质上是将原来的 \(a_j - x_i\) 代替新的 \(a_j\) ,只需要查询的区间更改一下就可以了

因为要回答区间的答案,所以还要把线段树可持久化一下,每次查询从高到低枚举 \(b_i\) 的每一位看看能否选相反的即可



/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
} const int N = 1000005, len = (1 << 19) - 1;
int rt[N], n, m; struct SegmentTree{
int sz[N*25], lc[N*25], rc[N*25], size;
inline void ins(int &u, int pr, int l, int r, int pos){
u = ++size;
lc[u] = lc[pr], rc[u] = rc[pr], sz[u] = sz[pr] + 1;
if(l == r) return;
int mid = l + r >> 1;
if(pos <= mid) ins(lc[u], lc[pr], l, mid, pos);
else ins(rc[u], rc[pr], mid + 1, r, pos);
}
inline int query(int x, int y, int l, int r, int L, int R){
if(l >= L && r <= R) return (sz[y] - sz[x] > 0);
int mid = l + r >> 1, res = 0;
if(L <= mid) res |= query(lc[x], lc[y], l, mid, L, R);
if(mid < R) res |= query(rc[x], rc[y], mid + 1, r, L, R);
return res;
}
}van; int main(){
read(n), read(m);
for(int i = 1, x; i <= n; i++)
read(x), van.ins(rt[i], rt[i-1], 0, len, x); while(m--){
int now, add, l = 0, r = len, res = 0, L, R;
read(now), read(add), read(L), read(R);
for(int i = 18; ~i; i--){
int s = ((now >> i) & 1) ^ 1, mid = l + r >> 1;
int nl = s ? mid + 1 : l, nr = s ? r : mid;
if(van.query(rt[L-1], rt[R], 0, len, Max(nl - add, 0), Max(nr - add, 0)))
res |= 1 << i, l = nl, r = nr;
else l = s ? l : mid + 1, r = s ? mid : r;
}
printf("%d\n", res);
}
return 0;
}

「SCOI2016」美味的更多相关文章

  1. 「SCOI2016」美味 解题报告

    「SCOI2016」美味 状态极差无比,一个锤子题目而已 考虑每次对\(b\)和\(d\)求\(c=d \ xor \ (a+b)\)的最大值,因为异或每一位是独立的,所以我们可以尝试按位贪心. 如果 ...

  2. loj#2016. 「SCOI2016」美味

    题目链接 loj#2016. 「SCOI2016」美味 题解 对于不带x的怎么做....可持久化trie树 对于带x,和trie树一样贪心 对于答案的二进制位,从高往低位贪心, 二进制可以表示所有的数 ...

  3. AC日记——「SCOI2016」美味 LiBreOJ 2016

    #2016. 「SCOI2016」美味 思路: 主席树: 代码: #include <bits/stdc++.h> using namespace std; #define maxa 26 ...

  4. 【LOJ】#2016. 「SCOI2016」美味

    题解 做了一下SCOI2015,于是决定搬运SCOI2016= v = 如果没有加法,我们可以向左向右节点查找 每个总权值是2^18 - 1,然后左右分,那么每次是一个完整的节点 如果有了加法,那么我 ...

  5. loj2016 「SCOI2016」美味

    trie 树思想运用到主席树上orz #include <iostream> #include <cstdio> using namespace std; int n, m, ...

  6. 「SCOI2016」围棋 解题报告

    「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...

  7. 「SCOI2016」妖怪 解题报告

    「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...

  8. 「SCOI2016」萌萌哒 解题报告

    「SCOI2016」萌萌哒 这思路厉害啊.. 容易发现有个暴力是并查集 然后我想了半天线段树优化无果 然后正解是倍增优化并查集 有这个思路就简单了,就是开一个并查集代表每个开头\(i\)每个长\(2^ ...

  9. 「SCOI2016」背单词 解题报告

    「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...

随机推荐

  1. 20155117 王震宇 2006-2007-2 《Java程序设计》第三周学习总结

    20155117 王震宇 2006-2007-2 <Java程序设计>第三周学习总结 教材学习内容总结 在JAVA程序编写中,常常要用到对象(Object),要产生对象首先要定义类(Cla ...

  2. python学习笔记(十二)之函数

    牛刀小试: 定义一个无参函数 >>> def myFirstFunc(): ... print("Hello python") ... print("h ...

  3. 聊聊spring的那些扩展机制

    1.背景 慎入:本文将会有大量代码出入. 在看一些框架源码的时候,可以看见他们很多都会和Spring去做结合.举个例子dubbo的配置: 很多人其实配置了也就配置了,没有去过多的思考:为什么这么配置s ...

  4. hihoCoder 1174 : 拓扑排序·一

    题目链接:http://hihocoder.com/problemset/problem/1174 题目是中文题面我就不说题意了,要看题面的请点击上方链接~ 代码实现如下: #include < ...

  5. NYOJ 136 等式 (哈希)

    题目链接 描述 有以下等式:a1x13+a2x23+a3x33+a4x43+a5*x53=0 x1,x2,x3,x4,x5都就在区间[-50,50]之间的整数,且x1,x2,x3,x4,x5都不等于0 ...

  6. Dijkstra算法(转)

    基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求 ...

  7. Linux进程的创建函数fork()及其fork内核实现解析【转】

    转自:http://www.cnblogs.com/zengyiwen/p/5755193.html 进程的创建之fork() Linux系统下,进程可以调用fork函数来创建新的进程.调用进程为父进 ...

  8. python之smtplib库学习

    # -*- coding:utf-8 -*- import smtplibfrom email.mime.text import MIMETextfrom email import encodersf ...

  9. [ python ] 练习作业 - 3

    1. 写出Python查找一个变量的顺序 提示:4中作用域的顺序 本地作用域(local) --> 当前作用域被嵌入的本地作用域(enclsing locals) --> 全局/模块作用域 ...

  10. 重置HTML标签样式

    ;;} header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:bl ...