传送门


什么可持久化树套树才不会写呢,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的更多相关文章

  1. BZOJ3489 A simple rmq problem 【可持久化树套树】*

    BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...

  2. BZOJ3489: A simple rmq problem

    设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...

  3. bzoj3489: A simple rmq problem (主席树)

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  4. 【kd-tree】bzoj3489 A simple rmq problem

    Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre ...

  5. bzoj3489 A simple rmq problem 可持久化树套树

    先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R] ...

  6. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  7. 【BZOJ3489】A simple rmq problem

    [BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...

  8. 【BZOJ3489】A simple rmq problem kd-tree

    [BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...

  9. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

随机推荐

  1. Python基础知识点

    自学记录: 1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让 ...

  2. VR技术了解(作业)

    增强现实技术 概念:将现实世界和虚拟世界无缝集成的新技术. 突出特点: 真实世界与虚拟的信息集成 实时交互 三维空间中增添定位虚拟物 应用 医疗领域:医生可以利用增强现实技术,轻易地进行手术部位的精确 ...

  3. C程序

    /* 不适用C库函数,只是用 C 语言实现函数 void* memcpy( void *dst, const void *src, size_t len ) memmove 函数的功能是拷贝 src ...

  4. DAY3(PYTHON)字符串切片

    字符串调整: capitalize()   #首字母大写 upper()        #全大写 lower()      #全小写 swapcase() #大小写翻转 字符串切片: 顾头不顾尾!!! ...

  5. (网页)html中页面传递参数不用cookie不用缓存,js方法搞定

    function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...

  6. 【PHPStorm使用手册】如何设置字体大小?

    方案一:鼠标滚轮设置 打开窗口 file -> settings -> Editor -> General, 勾上选项“Change font size(Zoom) with Ctr ...

  7. spring mvc 中 controller 路径配置

    下图中,由于红色部分(value="/")的存在,导致 host:port/项目/dimlist 无法被映射到dimList方法,解决办法是将其去掉. package cn.bgo ...

  8. xxx.jar或者xxx.war中没有主清单属性和spring-boot-maven-plugin的作用

    因为springboot本身集成了tomcat插件,所以我们可以直接使用mvn clean package命令打成jar包或者war包,然后使java -jar xxx.jar 或者 java -ja ...

  9. SpringBoot自定义属性配置以及@ConfigurationProperties注解与@Value注解区别

    我们可以在application.properties中配置自定义的属性值,为了获取这些值,我们可以使用spring提供的@value注解,还可以使用springboot提供的@Configurati ...

  10. Cs231n课堂内容记录-Lecture2-Part1 图像分类

    Lecture 2 课程内容记录:(上)https://zhuanlan.zhihu.com/p/20894041?refer=intelligentunit (下)https://zhuanlan. ...