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. uniapp如何使用阿里iconfont

    1.将iconfont中需要的图标,添加到购物车,然后添加到自己的项目.生成在线代码. 2.点击下载至本地.然后解压后复制 iconfont.css 文件到你的项目. 3.复制第一步生成的代码,替换i ...

  2. Thinking In Java 4th Chap2 一切都是对象

    对基本数据类型的初始化有二: 1.String s="asdf"; 2.String s=new String("asdf"); 可能的存储区域: 寄存器(不可 ...

  3. python3 虚拟环境的创建

    创建虚拟环境的方法有很多种,我来分享一下我最常用的虚拟环境的创建方法和一些命令的使用, 什么是虚拟环境? 知道的可以略过,不知道的可以听我简单的说下.虚拟环境这四个字,一听你就明白什么意思了,首先理解 ...

  4. 环信联合创始人: Saas敏捷开发实践!

    马晓宇 --环信联合创始人/执行总裁 我们是一个做云服务的创业公司,所以我就云服务创业公司的角度,来谈谈我们是怎么去实践敏捷开发的.确切地说,就是讲讲我们这几年的这些教训... 1-创业公司敏捷开发流 ...

  5. EFcore的 基础理解<一>

    1.新建.netCore Web项目.这时候,还与EF没啥关系. 2.然后添加类 Bolg.和 Post   参考这里  https://docs.microsoft.com/en-us/ef/cor ...

  6. 安装laravel-ide-helper

    前言 使用laravel作为PHP开发框架的朋友都知道,laravel提供的门面操作都对于PHPStorm的代码提示和方法跳转都不是很友好.然而没有关系,今天介绍一个组件帮助到我们.就是!就是!就是! ...

  7. parseInt parseFloat Number三者转换的方式

    1.parseInt:从左到右检测字符串,若能先检测到数字,则将数字转换成整形,否则返回NaN. 2.parseFloat:从左到右检测字符串,若能先检测到数字,则将数字转换成浮点型,否则返回NaN. ...

  8. 许愿墙JQ

    <!doctype html> <html> <head>     <meta charset="utf-8">     <t ...

  9. android适配知识总结

    一.http适配 背景:API升级到28以后,不再支持明文的网络请求,只支持https请求.运行所报错误:java.net.UnknownServiceException: CLEARTEXT com ...

  10. CentOS自动备份MySql

    1.确认Crontab是否安装 service crond startcrontab -l 2.编写备份脚本 cd mkdir backup cd backup vim auto.sh /usr/bi ...