BZOJ_3489_ A simple rmq problem_KDTree

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

10 10
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

4
10
10
0
0
10
0
4
0
4

HINT

注意出题人为了方便,input的第二行最后多了个空格。

2015.6.24新加数据一组,2016.7.9放至40S,600M,但未重测


设ai上一次出现的位置为pre[i],下一次出现的位置为nxt[i],则我们需要找一个ai最大的点,使得l<=i<=r,pre[i]<l,nxt[i]>r。

使用三维KDTree即可。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define N 100050
int ch[N][2],mx[N][3],mn[N][3],root,now,mxv[N],n,ans,m,tt[N];
#define ls ch[p][0]
#define rs ch[p][1]
#define _min(x,y) ((x)<(y)?(x):(y))
#define _max(x,y) ((x)>(y)?(x):(y))
#define _(x) (x==2?0:x+1)
struct Point {
int p[3],v;
bool operator < (const Point &x) const {
int t=_(now);
if(p[now]==x.p[now]&&p[t]==x.p[t]) return p[_(t)]<x.p[_(t)];
if(p[now]==x.p[now]) return p[t]<x.p[t];
return p[now]<x.p[now];
}
}a[N];
void pushup(int p,int x) {
int i;
for(i=0;i<3;i++) {
mn[p][i]=_min(mn[p][i],mn[x][i]);
mx[p][i]=_max(mx[p][i],mx[x][i]);
}
mxv[p]=_max(mxv[p],mxv[x]);
}
int build(int l,int r,int type) {
int mid=(l+r)>>1; now=type;
nth_element(a+l,a+mid,a+r+1);
int i;
for(i=0;i<3;i++) mn[mid][i]=mx[mid][i]=a[mid].p[i];
mxv[mid]=a[mid].v;
if(l<mid) ch[mid][0]=build(l,mid-1,_(type)),pushup(mid,ch[mid][0]);
if(r>mid) ch[mid][1]=build(mid+1,r,_(type)),pushup(mid,ch[mid][1]);
return mid;
}
void query(int l,int r,int p) {
if(!p||mxv[p]<=ans||mx[p][0]<l||mn[p][0]>r||mn[p][1]>=l||mx[p][2]<=r) return ;
if(a[p].p[0]>=l&&a[p].p[0]<=r&&a[p].p[1]<l&&a[p].p[2]>r) ans=_max(ans,a[p].v);
query(l,r,ls); query(l,r,rs);
}
int main() {
scanf("%d%d",&n,&m);
int i,x,y;
for(i=1;i<=n;i++) {
scanf("%d",&x);
a[i].p[0]=i;
a[i].p[1]=tt[x];
a[tt[x]].p[2]=i;
tt[x]=i;
a[i].v=x;
}
for(i=1;i<=n;i++) if(!a[i].p[2]) a[i].p[2]=n+1;
root=build(1,n,0);
for(i=1;i<=m;i++) {
scanf("%d%d",&x,&y);
int l=min((x+ans)%n+1,(y+ans)%n+1),r=max((x+ans)%n+1,(y+ans)%n+1);
ans=0; query(l,r,root);
printf("%d\n",ans);
}
}

BZOJ_3489_ A simple rmq problem_KDTree的更多相关文章

  1. [bzoj3489]A simple rmq problem_KD-Tree

    A simple rmq problem 题目大意:给定一个长度为$n$的序列,给出$m$个询问:在$[l,r]$之间找到一个在这个区间里只出现过一次的最大的数. 注释:$1\le n\le 10^5 ...

  2. BZOJ 3489: A simple rmq problem

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

  3. 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][ ...

  4. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  5. 【BZOJ】【3489】A simple rmq problem

    KD-Tree(乱搞) Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]) ...

  6. 【BZOJ3489】A simple rmq problem

    [BZOJ3489]A simple rmq problem 题面 bzoj 题解 这个题不强制在线的话随便做啊... 考虑强制在线时怎么搞 预处理出一个位置上一个出现的相同数的位置\(pre\)与下 ...

  7. BZOJ3489 A simple rmq problem 【可持久化树套树】*

    BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...

  8. 【BZOJ3489】A simple rmq problem kd-tree

    [BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...

  9. BZOJ3489: A simple rmq problem

    设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...

随机推荐

  1. Linux 网卡驱动学习(二)(网络驱动接口小结)

    [摘要]前文我们分析了一个虚拟硬件的网络驱动例子,从中我们看到了网络设备的一些接口,其实网络设备驱动和块设备驱动的功能比较类似,都是发送和接收数据包(数据请求).当然它们实际是有很多不同的. 1.引言 ...

  2. 学会用core dump调试程序错误

    最来在项目中遇到大型程序出现SIGSEGV ,一直不知道用core dump工具来调试程序,花了近一周的时间,才定位问题,老大很生气,后果很严重,呵呵,事后仔细学习了这块的知识,了解一点core du ...

  3. 使用纯CSS3实现一个日食动画

    日食现象是月亮挡在了地球和太阳之间,也就是月亮遮挡住了太阳. 所以要构造日食,我们须要2个对象:一个代表月亮,一个代表太阳. <div class="eclipse sun" ...

  4. hadoop安全之hftp

    hftp默认是打开的,同意以浏览器的方式訪问和下载文件,以此方式下,能够读取全部文件,留下了安全隐患. 測试例如以下 /user/hive/warehouse/cdntest.db/selfreado ...

  5. Win8 使用经验之飞鸽传书

    参考资料: http://jingyan.baidu.com/article/c1a3101eb52cd8de656deba6.html Win8的UAC关闭不生效?彻底关闭Win8的UAC? 1. ...

  6. RobotFramework --RIDE介绍

    RIDE是robotframework的图形操作前端,我们在RIDE上进行测试用例设计和编写测试脚本,并执行自动化测试.下面来全面的认识下这个操作工具. 在右边编辑页面有三大模块,Edit,TextE ...

  7. Audio原理图设计

    1.DMIC 1)当双MIC时,通过MIC上的Selection PIN脚PULL  U/D进行左右channel选择.

  8. professional cuda c programming--CUDA库简单介绍

    CUDA Libraries简单介绍   上图是CUDA 库的位置.本文简要介绍cuSPARSE.cuBLAS.cuFFT和cuRAND.之后会介绍OpenACC. cuSPARSE线性代数库,主要针 ...

  9. GoogleFusionTablesAPI初探地图与云计算

    http://developer.51cto.com/art/200906/129324.htm http://yexiaochai.iteye.com/blog/1893735 http://yex ...

  10. android:PopupWindow的使用场景和注意事项

    1.PopupWindow的特点 借用Google官方的说法: "A popup window that can be used to display an arbitrary view. ...