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. Jquery对表单、表格的操作以及应用

    表单的应用 (1)表单标签:包含处理表单数据所用的服务器端程序URL以及数据提交到服务器的方法 (2)表单域:包含文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框.和文件上传框 (3)表 ...

  2. 剑指offer38:输入一棵二叉树,求该树的深度

    1 题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 2 思路和方法 深度优先搜索,每次得到左右子树当前最大路径,选择 ...

  3. LC 1. Two Sum

    题目介绍 Given an array of integers, return indices of the two numbers such that they add up to a specif ...

  4. 使用rsync工具构建php项目管理平台

    对于phper来说部署项目和更新项目是很方便的,只要直接将写好的项目覆盖到项目的根目录就可以啦.但是平时项目开发的时候肯定不是只部署一个环境,一般是三套环境(开发环境.测试环境.生产环境),我们每次在 ...

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

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

  6. Log4net采用外部配置文件和多记录器的方法

    1) 创建配置文件,可以放在任意位置,名字可以任意的xml文件 例如,文件名 Log.Config.xml,内容如下 <?xml version="1.0" encoding ...

  7. StoneTab标签页CAD插件 3.2.6

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  8. [NOIP10.5模拟赛]3.c题解--思维

    题目链接 这次不咕了 https://www.luogu.org/problemnew/show/AT2389 闲扯 考场20分爆搜走人 \cy 话说这几天T3都很考验思维啊 分析 我们先钦定一只鸡( ...

  9. kubernetes 集群内部访问外部的数据库endpoint

    k8s访问集群外独立的服务最好的方式是采用Endpoint方式,以mysql服务为例: 创建mysql-service.yaml apiVersion: v1 kind: Service metada ...

  10. windows批处理来执行java程序

    新建后缀名为.bat的文件,然后用记事本编辑,如果用sublime高级记事本编辑最好. @echo off % mshta vbscript:CreateObject()(window.close)& ...