【BZOJ3489】A simple rmq problem

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,但未重测

题解:在[l,r]中只出现一次等价于:上一次出现的位置<l&&l<=这次出现的位置<=r&&下一次出现的位置>r。然后写个三维kd-tree就行了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep for(int i=0;i<3;i++)
#define D1 ((D+1)%3)
#define D2 ((D+2)%3)
using namespace std;
const int maxn=100010;
int A,B,D,n,m,ans,root;
int head[maxn],pre[maxn],next[maxn],buc[maxn],v[maxn];
struct kd
{
int v[3],sm[3],sn[3],ls,rs,ms,s;
kd (){}
kd (int a,int b,int c,int d){v[0]=sm[0]=sn[0]=a,v[1]=sm[1]=sn[1]=b,v[2]=sm[2]=sn[2]=c,s=ms=d,ls=rs=0;}
int & operator [] (int a) {return v[a];}
bool operator < (kd a) const
{
return (v[D]==a[D])?((v[D1]==a[D1])?(v[D2]==a[D2]):(v[D1]<a[D1])):(v[D]<a[D]);
}
};
kd t[maxn];
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void pushup(int x,int y)
{
rep t[x].sm[i]=max(t[x].sm[i],t[y].sm[i]),t[x].sn[i]=min(t[x].sn[i],t[y].sn[i]);
t[x].ms=max(t[x].ms,t[y].ms);
}
int build(int l,int r,int d)
{
if(l>r) return 0;
D=d;
int mid=l+r>>1;
nth_element(t+l,t+mid,t+r+1);
t[mid].ls=build(l,mid-1,(d+1)%3),t[mid].rs=build(mid+1,r,(d+1)%3);
if(t[mid].ls) pushup(mid,t[mid].ls);
if(t[mid].rs) pushup(mid,t[mid].rs);
return mid;
}
int check(int x)
{
if(t[x].ms<=ans||t[x].sm[0]<A||t[x].sn[0]>B||t[x].sn[1]>=A||t[x].sm[2]<=B) return 0;
return 1;
}
void query(int x)
{
if(!x||!check(x)) return ;
if(t[x][0]>=A&&t[x][0]<=B&&t[x][1]<A&&t[x][2]>B&&t[x].s>ans) ans=t[x].s;
query(t[x].ls),query(t[x].rs);
}
int main()
{
n=rd(),m=rd();
int i;
for(i=1;i<=n;i++)
{
v[i]=rd(),pre[i]=head[v[i]];
if(head[v[i]]) next[head[v[i]]]=i;
head[v[i]]=i;
}
for(i=1;i<=n;i++) if(!next[i]) next[i]=n+1;
for(i=1;i<=n;i++) t[i]=kd(i,pre[i],next[i],v[i]);
root=build(1,n,0);
for(i=1;i<=m;i++)
{
A=(ans+rd())%n+1,B=(ans+rd())%n+1;
if(A>B) swap(A,B);
ans=0,query(root);
printf("%d\n",ans);
}
return 0;
}

【BZOJ3489】A simple rmq problem kd-tree的更多相关文章

  1. 【bzoj3489】 A simple rmq problem k-d树

    由于某些原因,我先打了一个错误的树套树,后来打起了$k-d$.接着因不明原因在思路上被卡了很久,在今天中午蹲坑时恍然大悟...... 对于一个数字$a_i$,我们可以用一组三维坐标$(i,pre,nx ...

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

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

  3. 【BZOJ3489】A simple rmq problem

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

  4. 【BZOJ3489】A simple rmq problem【kd树】

    题意 给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. 分析 预处理 ...

  5. 【bzoj3489】 A simple rmq problem

    http://www.lydsy.com/JudgeOnline/problem.php?id=3489 (题目链接) 题意 在线求区间不重复出现的最大的数. Solution KDtree竟然能够处 ...

  6. 【bzoj3489】A simple rmq problem 三维KD-tree

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

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

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

  8. BZOJ3489 A simple rmq problem K-D Tree

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

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

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

随机推荐

  1. getchar吸收回车

    #include "stdio.h" int main() { int a; char b,c; scanf("%d",&a); c = getchar ...

  2. (5)centos图形界面安装

    1.登录 2.先安装MATE可视化桌面 yum groups install "MATE Desktop" 选择y 3.安装X Window System:图形接口 yum gro ...

  3. LOJ N!在不同进制的位数

    lightoj1045 - Digits of Factorial (N!不同进制的位数) 对于一个B进制的数,只需要对其取以B的对数就可以得到他在B进制情况下的位数(取了对数之后可能为小数,所以还需 ...

  4. JUC线程池深入刨析

    JDK默认提供了四种线程池:SingleThreadExecutor.FiexdThreadPool.CachedThreadPool.ScheduledThreadPoolExecutor. 本文会 ...

  5. 我的CSS初始化,reset.css

    * { margin:; padding:; text-decoration: none; -webkit-overflow-scrolling: touch !important; /*iOS惯性滚 ...

  6. 【spring boot】9.spring boot+spring-data-jpa的入门使用,实现数据持久化

    spring-data-jpa官方使用说明文档:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/ spring-d ...

  7. 亿图图示专家V7破解版

    “破解文件”目录下的三个文件拷贝出来复制到安装目录下即可: 下载链接地址: http://cloud.suning.com/cloud-web/share/link.htm?sk=718100ef90 ...

  8. springnodejs

    作者 : solq 最新文档请看 http://www.springnodejs.com 本文不再更新 blog : http://www.cnblogs.com/solq/p/3574640.htm ...

  9. 手机APP自动化持续集成方案

    自动化测试流程 自动化测试框架

  10. 版本号控制软件:TortoiseSVN高速上手

    百度百科对于SVN的一点解释: TortoiseSVN是Subversion版本号控制系统的一个免费开源client,能够超越时间的管理文件和文件夹.文件保存在中央版本号库,除了能记住文件和文件夹的每 ...