KD树水过这道可持久化树套树…其实就是个三维偏序 题解戳这里

CODE

#include <bits/stdc++.h>
using namespace std;
#define ls (t[o].ch[0])
#define rs (t[o].ch[1])
const int MAXN = 100005;
const int inf = 1e9;
inline void read(int &num) {
char ch; int flg=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
int D, rt;
struct Node {
int d[3], v;
inline bool operator <(const Node &o)const {
return d[D] < o.d[D];
}
}arr[MAXN];
struct KD_node {
int ch[2], mn[3], mx[3], val;
Node a;
inline void clear() {
ch[0]=ch[1]=val=a.v=0;
for(int l = 0; l < 3; ++l)
mn[l]=mx[l]=a.d[l]=0;
}
}t[MAXN];
struct Query {
int mn[3], mx[3];
};
int bin[MAXN], top, tot, cur;
inline int NewNode() {
if(!top) return ++tot;
t[bin[top]].clear();
return bin[top--];
}
inline void chkmin(int &x, int y) { if(y < x) x = y; }
inline void chkmax(int &x, int y) { if(y > x) x = y; }
inline void mt(int x, int y) {
for(int l = 0; l < 3; ++l)
chkmin(t[x].mn[l], t[y].mn[l]),
chkmax(t[x].mx[l], t[y].mx[l]);
chkmax(t[x].val, t[y].val);
}
inline void upd(int o) {
for(int l = 0; l < 3; ++l)
t[o].mn[l] = t[o].mx[l] = t[o].a.d[l];
t[o].val = t[o].a.v;
if(ls) mt(o, ls);
if(rs) mt(o, rs);
}
inline int build(int l, int r, int nd) {
int mid = (l + r) >> 1; D = nd;
nth_element(arr+l, arr+mid, arr+r+1);
int o = NewNode(); t[o].a = arr[mid];
if(l < mid) ls = build(l, mid-1, (nd+1)%3); else ls = 0;
if(r > mid) rs = build(mid+1, r, (nd+1)%3); else rs = 0;
upd(o); return o;
}
inline int judge(int o, Query q) {
if(q.mn[0] <= t[o].mn[0] && t[o].mx[0] <= q.mx[0]
&& q.mn[1] <= t[o].mn[1] && t[o].mx[1] <= q.mx[1]
&& q.mn[2] <= t[o].mn[2] && t[o].mx[2] <= q.mx[2]) return 1;
if(q.mn[0] > t[o].mx[0] || q.mx[0] < t[o].mn[0]
|| q.mn[1] > t[o].mx[1] || q.mx[1] < t[o].mn[1]
|| q.mn[2] > t[o].mx[2] || q.mx[2] < t[o].mn[2]) return -1;
return 0;
}
int lastans;
inline void query(int o, Query q) {
if(!o || t[o].val <= lastans) return;
int tmp = judge(o, q);
if(tmp == 1) chkmax(lastans, t[o].val);
else if(tmp == -1) return;
else {
if(q.mn[0] <= t[o].a.d[0] && t[o].a.d[0] <= q.mx[0]
&& q.mn[1] <= t[o].a.d[1] && t[o].a.d[1] <= q.mx[1]
&& q.mn[2] <= t[o].a.d[2] && t[o].a.d[2] <= q.mx[2])
chkmax(lastans, t[o].a.v);
int which = t[ls].val < t[rs].val;
query(t[o].ch[which], q);
query(t[o].ch[which^1], q);
}
}
int n, m;
int num[MAXN], pre[MAXN], suf[MAXN], lst[MAXN];
int main () {
read(n), read(m);
for(int i = 1; i <= n; ++i) lst[i] = 0, read(num[i]);
for(int i = 1; i <= n; ++i) pre[i] = lst[num[i]], lst[num[i]] = i;
for(int i = 1; i <= n; ++i) lst[i] = n+1;
for(int i = n; i >= 1; --i) suf[i] = lst[num[i]], lst[num[i]] = i;
for(int i = 1; i <= n; ++i) arr[i] = (Node){{i, pre[i], suf[i]}, num[i]};
rt=build(1, n, 0);
int x, y;
for(int i = 1; i <= m; ++i) {
read(x), read(y);
x = (lastans + x) % n + 1,
y = (lastans + y) % n + 1;
if(y < x) swap(x, y);
lastans = 0;
query(rt, (Query){{x, 0, y+1}, {y, x-1, n+1}});
printf("%d\n", lastans);
}
}

BZOJ 3489: A simple rmq problem (KD-tree做法)的更多相关文章

  1. BZOJ 3489: A simple rmq problem(K-D Tree)

    Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2579  Solved: 888[Submit][Status][Discuss] Descripti ...

  2. bzoj 3489: A simple rmq problem k-d树思想大暴力

    3489: A simple rmq problem Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 551  Solved: 170[Submit][ ...

  3. BZOJ 3489: A simple rmq problem

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

  4. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

  5. BZOJ3489 A simple rmq problem K-D Tree

    传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...

  6. BZOJ.3489.A simple rmq problem(主席树 Heap)

    题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...

  7. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  8. BZOJ 3489 A simple rmq problem(可持久化线段树)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...

  9. BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...

  10. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

随机推荐

  1. HTML5页面如何在手机端浏览器调用相机、相册功能

    最近在做一个公司的保险信息处理系统项目,开发微信端浏览器访问的HTML5的页面,页面中有一个<input id="input" type="file"/& ...

  2. go 计算 MD5

    Golang的加密库都放在crypto目录下,其中MD5库在crypto/md5包中,该包主要提供了New和Sum函数 直接调用md5计算 package main import ( "cr ...

  3. 知乎Python后端面试总结

    一面 写个快速排序热热身,分析一下复杂度,如果不使用额外的空间,应该怎么写? 说一下Flask中g是怎么实现的,原理是什么? 说一下浏览器从输入url到页面渲染的过程,越详细越好: 了解web安全吗? ...

  4. java 复制指定目录中的所有文件和文件夹到另一个指定文件夹中

    package com.test; import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream ...

  5. 【Python基础】13_Python中的PASS

    pass关键字的使用 在程序分支中,如果不想立刻执行该分支,可使用pass占位符,pass不表示任何含义,仅保证程序不会报错. 如: action_str = input("请选择希望执行的 ...

  6. S03_CH04_AXI_DMA_OV5640摄像头采集系统

    S03_CH04_AXI_DMA_OV5640摄像头采集系统 4.1概述 本课程讲解如何搭建基于DMA的图形系统,方案原理和搭建7725的一样,只是OV5640显示的分辨率是1280X720如下,只是 ...

  7. Linux weblogic启停

    一般weblogic启停在windows下很方便使用图标方式.但是在linux下需要杀掉weblogic进程才能真正关掉weblogic. 1.查询weblogic进程 ps -ef | grep & ...

  8. windows下将jar包打入maven仓库

    mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java -Dversion=1.27 -Dpac ...

  9. linux 安装redis 完整步骤

    最近在linux服务器上需要安装redis,来存放数据,增加用户访问数据的速度,由于是第一次安装,于是在百度上搜了一篇文章,按照这篇博客,顺利安装好了,因此将博主的文章拷过来记录一下,方便以后使用,也 ...

  10. vue2.0和animate.css的结合使用

    animate.css是一款前端动画库,相似的有velocity-animate. 上述是一个完整的结构.其中重要的几个点用箭头表示出来.首先在transition组件内部,需要定义两个基本的clas ...