传送门


什么可持久化树套树才不会写呢,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 捕捉traceback异常栈信息

    捕捉traceback异常栈信息   by:授客 QQ:1033553122 相关函数简介 sys.exc_info() 返回包含3个元素(type, value, traceback)的元组,提供关 ...

  2. mysql的数据类型和字段属性

    本文内容: 数据类型 数值类型 整数型 浮点型 定点型 日期时间类型 字符串类型 补充: 显示宽度与zerofll 记录长度 字段属性 空\不为空值:NULL.NOT NULL 主键:primary ...

  3. Jmeter-测试计划,线程组,取样器,逻辑控制器,断言和监听器

    一 测试计划: 是使用jmeter测试的起点,是其他测试元件的容器,一个完整的测试计划包括多个线程组,逻辑控制器,取样器,监听器,配置元件 用户定义的变量: 测试计划上可以添加用户定义的变量.一般添加 ...

  4. Linux下Wheel用户组介绍

    昨天遇到一个很奇怪的事情,有一台服务器在使用su - root命令切换到root账号时,老是报密码不正确.但是root密码完全是正确的,而且可以使用账号密码直接ssh登录服务器.很是纳闷,如下所示: ...

  5. MSSQL sql server order by 1,2 的具体含义

    转自:http://www.maomao365.com/?p=5416 摘要: order by 1,2 的含义是对表的第一列  按照从小到大的顺序进行排列 然后再对第二列按照从小到大的顺序进行排列 ...

  6. Dockfile制作镜像

    讲一个简单的案例 @哈希码用来校验,这样子会安全 MAINTANIER可能将会被LABEL代替,仅仅说说明一下镜像信息罢了. 1.首先是我们创建一个镜像 [root@ELK-chaofeng08 ~] ...

  7. Sudoku 小项目

    Sudoku 小项目 - 软工第二次作业 Part 1 · 项目相关 Github 地址: https://github.com/TheSkyFucker/Sudoku 项目的更多信息以及所有开发文档 ...

  8. JDBC复习2

    前面复习了一些基础知识以及如何抽取一些常用的代码,接下来就结合junit4做一个增删改查的小demo 重点是这么几个步骤:1.创建连接 2.编写sql语句 3.编写sql语句的载体 4.如果是Prep ...

  9. 【teradata】强制解锁

    使用加锁用户释放锁,也可以用其它用户使用如下语句强制解锁 Release lock (pdm_data ),Override

  10. aliyun mysql

    https://segmentfault.com/q/1010000009603559?sort=created