BZOJ3489 A simple rmq problem K-D Tree
什么可持久化树套树才不会写呢,K-D Tree大法吼啊
对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个询问\((l,r)\)和一个位置\(i\),需要同时满足\(pre_i < l \leq i \leq r < aft_i\)时,第\(i\)个位置的值才能产生贡献。
将\((pre_i , i , aft_i)\)看作三维空间中的一个点,那么能够产生贡献的一些点就会在一个立方体范围内。使用K-D Tree进行搜索即可。
记得要加一些剪枝,比如当前访问的区域的最大值比当前答案小就退出等
记得一定不要把nth_element(n + l , n + mid , n + r + 1)写成nth_elemet(n + l , n + r + 1 , n + mid)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return f ? -a : a;
}
const int MAXN = 1e5 + 7;
struct node{
int pos[3] , val;
}nd[MAXN];
int N , M , lastans , ind[MAXN];
int pre[MAXN] , ch[MAXN][2] , maxV[MAXN] , maxP[MAXN][3] , minP[MAXN][3];
bool cmp0(node a , node b){return a.pos[0] < b.pos[0];}
bool cmp1(node a , node b){return a.pos[1] < b.pos[1];}
bool cmp2(node a , node b){return a.pos[2] < b.pos[2];}
inline int pushup(int x){
memcpy(maxP[x] , nd[x].pos , sizeof(nd[x].pos));
memcpy(minP[x] , nd[x].pos , sizeof(nd[x].pos));
maxV[x] = nd[x].val;
for(int p = 0 ; p < 2 ; ++p)
if(ch[x][p]){
maxV[x] = max(maxV[x] , maxV[ch[x][p]]);
for(int i = 0 ; i < 3 ; ++i){
maxP[x][i] = max(maxP[x][i] , maxP[ch[x][p]][i]);
minP[x][i] = min(minP[x][i] , minP[ch[x][p]][i]);
}
}
return x;
}
int build(int l , int r , int tp){
if(l > r) return 0;
if(l == r) return pushup(l);
int mid = (l + r) >> 1;
nth_element(nd + l , nd + mid , nd + r + 1 , tp == 0 ? cmp0 : (tp == 1 ? cmp1 : cmp2));
ch[mid][0] = build(l , mid - 1 , (tp + 1) % 3);
ch[mid][1] = build(mid + 1 , r , (tp + 1) % 3);
return pushup(mid);
}
long long cnt;
void query(int cur , int a , int b){
if(minP[cur][0] >= a || maxP[cur][2] <= b || minP[cur][1] > b || maxP[cur][1] < a || maxV[cur] <= lastans) return;
if(maxP[cur][0] < a && minP[cur][2] > b && minP[cur][1] >= a && maxP[cur][1] <= b){
lastans = maxV[cur]; return;
}
if(nd[cur].pos[0] < a && nd[cur].pos[1] >= a && nd[cur].pos[1] <= b && nd[cur].pos[2] > b)
lastans = max(lastans , nd[cur].val);
query(ch[cur][0] , a , b); query(ch[cur][1] , a , b);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
freopen("out","w",stdout);
#endif
N = read(); M = read();
for(int i = 1 ; i <= N ; ++i){
nd[i].pos[1] = i;
int a = nd[i].val = read();
nd[i].pos[0] = pre[a]; nd[pre[a]].pos[2] = i;
pre[a] = i;
}
for(int i = 1 ; i <= N ; ++i)
nd[pre[i]].pos[2] = N + 1;
int rt = build(1 , N , 0);
while(M--){
int x = (read() + lastans) % N + 1 , y = (read() + lastans) % N + 1;
if(x > y) x ^= y ^= x ^= y;
lastans = 0;
query(rt , x , y);
printf("%d\n" , lastans);
}
return 0;
}
BZOJ3489 A simple rmq problem K-D Tree的更多相关文章
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
- BZOJ3489: A simple rmq problem
设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...
- bzoj3489: A simple rmq problem (主席树)
//========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/ 转载要声明! //=============== ...
- 【kd-tree】bzoj3489 A simple rmq problem
Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre ...
- bzoj3489 A simple rmq problem 可持久化树套树
先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R] ...
- 【BZOJ3489】A simple rmq problem(KD-Tree)
[BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...
- 【BZOJ3489】A simple rmq problem
[BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...
- 【BZOJ3489】A simple rmq problem kd-tree
[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...
- BZOJ 3489: A simple rmq problem
3489: A simple rmq problem Time Limit: 40 Sec Memory Limit: 600 MBSubmit: 1594 Solved: 520[Submit] ...
随机推荐
- iOS开发GCD(3)-数据安全
/* 多个线程可能访问同一块资源,造成数据错乱和数据安全问题 为代码添加同步锁(互斥锁) */ -(void)synchronized{ @synchronized(self){ //需要锁住的代码, ...
- (后端)Sql Server日期查询-SQL查询今天、昨天、7天内、30天(转)
今天的所有数据: 昨天的所有数据: 7天内的所有数据: 30天内的所有数据: 本月的所有数据: 本年的所有数据: 查询今天是今年的第几天: select datepart(dayofyear,getD ...
- vue自动完成搜索功能的数据请求处理
在现在的互联网世界里,自动完成的搜索功能是一个很常见的功能.比如百度.搜狗.360搜索 ... 功能描述一下大概是这个样子的:有一个搜索框,用户在里面输入要查询的条件,系统会“智能”判断用户输完了,然 ...
- mysql的数据类型和字段属性
本文内容: 数据类型 数值类型 整数型 浮点型 定点型 日期时间类型 字符串类型 补充: 显示宽度与zerofll 记录长度 字段属性 空\不为空值:NULL.NOT NULL 主键:primary ...
- Python 实例方法、类方法、静态方法的区别与作用
Python中至少有三种比较常见的方法类型,即实例方法,类方法.静态方法.它们是如何定义的呢?如何调用的呢?它们又有何区别和作用呢?且看下文. 首先,这三种方法都定义在类中.下面我先简单说一下怎么定义 ...
- HandyEditor 富文本编辑器整合到python flask项目中
1.下载HandyEditor,地址http://he.catfish-cms.com/ 2.解压后的文件名HandyEditor-master改为HandyEditor,文件夹里的文件如下 3.将H ...
- 语句调优基础知识-set statistics io on
set statistics io on --清空缓存数据 dbcc dropcleanbuffers go --清空缓存计划 dbcc freeproccache go set statistics ...
- Greenplum启动失败Error occurred: non-zero rc: 1的修复
某日开发反馈测试环境的集群启动失败 报错内容如下: [gpadmin@hadoop-test2:/root]$ gpstart :::: gpstart:hadoop-test2:gpadmin-[I ...
- 自动化测试基础篇--Selenium Xpath定位
摘自https://www.cnblogs.com/sanzangTst/p/7458056.html 学习 什么是xpath? XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言 ...
- Ubuntu16.04下iTop4412环境搭建+Android4.0.3编译
系统:Ubuntu16.04.02(优麒麟) 安装库文件和JDK 使用cd 命令,进入解压出来的“Android_JDK” -->“jdk6”文件夹,运行脚本文件 “install-sun-ja ...