BZOJ 3489: A simple rmq problem
3489: A simple rmq problem
Time Limit: 40 Sec Memory Limit: 600 MB
Submit: 1594 Solved: 520
[Submit][Status][Discuss]
Description
因为是OJ上的题,就简单点好了。给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大。如果找不到这样的数,则直接输出0。我会采取一些措施强制在线。
Input
第一行为两个整数N,M。M是询问数,N是序列的长度(N<=100000,M<=200000)
第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N
再下面M行,每行两个整数x,y,
询问区间[l,r]由下列规则产生(OIER都知道是怎样的吧>_<):
l=min((x+lastans)mod n+1,(y+lastans)mod n+1);
r=max((x+lastans)mod n+1,(y+lastans)mod n+1);
Lastans表示上一个询问的答案,一开始lastans为0
Output
一共M行,每行给出每个询问的答案。
Sample Input
6 4 9 10 9 10 9 4 10 4
3 8
10 1
3 4
9 4
8 1
7 8
2 9
1 1
7 3
9 9
Sample Output
10
10
0
0
10
0
4
0
4
HINT
注意出题人为了方便,input的第二行最后多了个空格。
2015.6.24新加数据一组,2016.7.9放至40S,600M,但未重测
Source
参考了网上的一些做法,可持久化树套树什么的实在吃不消,于是采用了KD-Tree的方法。
考虑一个点,在哪个区间内它是唯一出现的呢?
设prev[i]为上一个和i处权值相同的位置,next[i]为下一个和i处权值相同的位置,显然在(prev[i],next[i])这个区间内,i点是该权值唯一出现的位置。
对于一个询问(ql,qr),我们可以转换为:找出满足 prev[i] < ql 且 next[i] > qr 且 ql <= i <= qr 的i中,权值最大的i。这个就是KD-Tree维护三维的区间最值问题。
#include <bits/stdc++.h>
inline int getC(void) {
static const int siz = ;
static char buf[siz];
static char *hd = buf + siz;
static char *tl = buf + siz;
if (hd == tl)
fread(hd = buf, , siz, stdin);
return int(*hd++);
}
inline int getI(void) {
register int ret = ;
register int neg = false;
register int bit = getC();
for (; bit < ; bit = getC())
if (bit == '-')neg ^= true;
for (; bit > ; bit = getC())
ret = ret * + bit - '';
return neg ? -ret : ret;
}
template <class T>
inline T min(const T &a, const T &b) {
return a < b ? a : b;
}
template <class T>
inline T max(const T &a, const T &b) {
return a > b ? a : b;
}
const int maxn = ;
int n, m;
int answer;
int num[maxn];
int next[maxn];
int prev[maxn];
int last[maxn];
int value[maxn][];
int pos[maxn];
int maxv[maxn];
int lson[maxn];
int rson[maxn];
int mini[maxn][];
int maxi[maxn][];
int qryL, qryR;
int cmpK;
inline bool cmp(const int &a, const int &b) {
return value[a][cmpK] < value[b][cmpK];
}
int build(int l, int r, int k) {
int mid = (l + r) >> ; cmpK = k;
std::nth_element(
pos + l, pos + mid, pos + r + , cmp);
maxv[mid] = num[pos[mid]];
for (int i = ; i < ; ++i)
mini[mid][i] = maxi[mid][i] = value[pos[mid]][i];
if (l < mid) {
lson[mid] = build(l, mid - , (k + ) % );
maxv[mid] = max(maxv[mid], maxv[lson[mid]]);
for (int i = ; i < ; ++i) {
mini[mid][i] = min(mini[mid][i], mini[lson[mid]][i]);
maxi[mid][i] = max(maxi[mid][i], maxi[lson[mid]][i]);
}
}
if (r > mid) {
rson[mid] = build(mid + , r, (k + ) % );
maxv[mid] = max(maxv[mid], maxv[rson[mid]]);
for (int i = ; i < ; ++i) {
mini[mid][i] = min(mini[mid][i], mini[rson[mid]][i]);
maxi[mid][i] = max(maxi[mid][i], maxi[rson[mid]][i]);
}
}
return mid;
}
inline bool check(int t) {
if (mini[t][] > qryR || maxi[t][] < qryL)return false;
if (mini[t][] >= qryL || maxi[t][] <= qryR)return false;
return true;
}
void query(int t) {
if (mini[t][] >= qryL && maxi[t][] <= qryR && maxi[t][] < qryL && mini[t][] > qryR)
{ answer = max(answer, maxv[t]); return; }
if (pos[t] >= qryL && pos[t] <= qryR && prev[pos[t]] < qryL && next[pos[t]] > qryR)
answer = max(answer, num[pos[t]]);
if (maxv[lson[t]] > maxv[rson[t]]) {
if (lson[t] && maxv[lson[t]] > answer && check(lson[t]))query(lson[t]);
if (rson[t] && maxv[rson[t]] > answer && check(rson[t]))query(rson[t]);
}
else {
if (rson[t] && maxv[rson[t]] > answer && check(rson[t]))query(rson[t]);
if (lson[t] && maxv[lson[t]] > answer && check(lson[t]))query(lson[t]);
}
}
signed main(void) {
n = getI();
m = getI();
for (int i = ; i <= n; ++i)
num[i] = getI();
for (int i = ; i <= n; ++i)
last[i] = ;
for (int i = ; i <= n; ++i)
prev[i] = last[num[i]], last[num[i]] = i;
for (int i = n; i >= ; --i)
last[i] = n + ;
for (int i = n; i >= ; --i)
next[i] = last[num[i]], last[num[i]] = i;
for (int i = ; i <= n; ++i) {
pos[i] = i;
value[i][] = i;
value[i][] = prev[i];
value[i][] = next[i];
}
int root = build(, n, );
for (int i = ; i <= m; ++i) {
int x = getI();
int y = getI();
qryL = (x + answer) % n + ;
qryR = (y + answer) % n + ;
if (qryL > qryR)
qryL ^= (qryR ^= (qryL ^= qryR));
answer = ; query(root); printf("%d\n", answer);
}
}
@Author: YouSiki
BZOJ 3489: A simple rmq problem的更多相关文章
- 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][ ...
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...
- bzoj 3489 A simple rmq problem - 线段树
Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...
- BZOJ 3489 A simple rmq problem(可持久化线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...
- BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...
- bzoj 3489 A simple rmq problem——主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
- bzoj 3489 A simple rmq problem —— 主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
- BZOJ.3489.A simple rmq problem(主席树 Heap)
题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...
- BZOJ 3489: A simple rmq problem(K-D Tree)
Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 2579 Solved: 888[Submit][Status][Discuss] Descripti ...
随机推荐
- HTML学习(一)基础篇
这篇文章有人比我总结的好,适用于新手,我就适当的铺垫一下,结尾处会给你们网站,我就不班门弄斧了. 一)HTML结构 1.<head>标签 <title> <base/&g ...
- UITextField
UITextFieldDemo 效果 特点 1.有效定制键盘的样式 2.处理键盘对文本框的遮挡 用法 1.导入文件(UITextField+CreateInputAccessoryView.h/.m) ...
- ASP.NET伪静态实现
ASP.NET伪静态实现 在asp.net下,如何自己写代码来实现伪静态呢?如何重写url地址呢? 例如:本来aspx的页面地址是:/default.aspx?id=1,我要重写成这样:/index- ...
- CentOS如何查看硬盘品牌型号等具体信息
首先使用smartctl --all /dev/sda 指令来检查硬盘信息,该指令CentOS自带,得到的结果可能如下: smartctl 5.43 2012-06-30 r3573 [x86_64- ...
- SQL Server 进阶 01 数据库的设计
SQL Server 进阶 01 数据库的设计 本篇目录 课程内容回顾及介绍 为什么需要规范的数据库设计 设计数据库的步骤 绘制E-R(实体-关系)图 实体-关系模型 如何将E-R图转换为表 数据规范 ...
- win10打开IL DASM步骤:
- 认识 EXT2 文件系统
认识ext文件系统 硬盘组成与分割 文件系统特性 Linux 的 EXT2 文件系统(inode) 与目录树的关系 EXT2/EXT3 文件的存取与日志式文件系统的功能 Linux 文件系统的运行 挂 ...
- android android BitmapFactory报错OOM
解决方法:listview中尽量不要使用ImageView作为item的组件 换成view并设background
- MMORPG大型游戏设计与开发(服务器 AI 逻辑设定和状态结点)
人工智能(AI)中往往都会有这么一个问题,那就是我要做什么?我该怎么做?我需要什么?所以这里所谓的智能就是赋予AI对象的判断力,以及它根据判断得到的相应反应.就好比,你去商店买东西,钱够别人才卖给你, ...
- web.xml中的welcome-file-list不起作用
今天尝试使用struts2+ urlrewrite+sitemesh部署项目,结果发现welcome-file-list中定义的欢迎页不起作用: <welcome-file-list> & ...