先预处理出两个个数组pre,next。pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0;next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1。那么一个满足在区间[L,R]中只出现一次的数字,其pre[i]<L,next[i]>R。

  这样我们可以先将pre进行排序,然后将pre可持久化,外层线段树套的是当前数字的位置i,内层线段树套的是next[i]。外层线段树的节点总数是nlogn,内层线段树节点总数是nlogn^2。时间复杂度O(nlogn^2)。

  代码

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define N 40000000
#define M 100010
#define Q 2000000
using namespace std;
int n,m,i,a[M],tmp[M],tt,stt,ls[Q],rs[Q],root[M],L,R,e[M];
int subroot[Q],u,v,ans;
struct ff
{
int next,pre,idx;
}f[M];
struct g
{
int ls,rs,s;
}sub[N];
inline void ll(int x,int y)
{
ls[x]=ls[y];
}
inline void rr(int x,int y)
{
rs[x]=rs[y];
}
inline void sl(int x,int y)
{
sub[x].ls=sub[y].ls;
}
inline void sr(int x,int y)
{
sub[x].rs=sub[y].rs;
}
bool cmp(ff a,ff b)
{
return a.pre<b.pre;
}
void subinsert(int &x,int y,int l,int r,int a,int b)
{
int m;
stt++;x=stt;
sub[x].s=max(sub[y].s,b);
if (r-l==) return;
m=(l+r)>>;
sl(x,y);
sr(x,y);
if (a-<m) subinsert(sub[x].ls,sub[y].ls,l,m,a,b);
if (m<a) subinsert(sub[x].rs,sub[y].rs,m,r,a,b);
}
void insert(int &x,int y,int l,int r,int a,int b,int c)
{
int m;
tt++;x=tt;
subinsert(subroot[x],subroot[y],,n+,b,c);
if (r-l==) return;
m=(l+r)>>;
ll(x,y);rr(x,y);
if (a-<m)
insert(ls[x],ls[y],l,m,a,b,c);
if (m<a)
insert(rs[x],rs[y],m,r,a,b,c);
}
int subquery(int x,int l,int r,int a,int b)
{
int m,ans=;
if (x==) return ;
if ((a<=l)&&(r<=b))
return sub[x].s;
m=(l+r)>>;
if (a<m) ans=max(ans,subquery(sub[x].ls,l,m,a,b));
if (m<b) ans=max(ans,subquery(sub[x].rs,m,r,a,b));
return ans;
}
int query(int x,int l,int r,int a,int b)
{
int m,ans=;
if (x==) return ;
if ((a<=l)&&(r<=b))
return subquery(subroot[x],,n+,b,n+);
m=(l+r)>>;
if (a<m) ans=max(ans,query(ls[x],l,m,a,b));
if (m<b) ans=max(ans,query(rs[x],m,r,a,b));
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for (i=;i<=n;i++)
scanf("%d",&a[i]);
for (i=;i<=n;i++)
{
f[i].pre=tmp[a[i]];
tmp[a[i]]=i;
}
for (i=;i<=n;i++)
tmp[i]=n+;
for (i=n;i>=;i--)
{
f[i].next=tmp[a[i]];
tmp[a[i]]=i;
f[i].idx=i;
}
sort(f+,f++n,cmp);
for (i=;i<=n;i++)
{
insert(root[i],root[i-],,n,f[i].idx,f[i].next,a[f[i].idx]);
}
for (i=;i<=n;i++)
e[f[i].pre]=i;
for (i=;i<=n;i++)
if (e[i]==)
e[i]=e[i-];
for (i=;i<=m;i++)
{
scanf("%d%d",&u,&v);
L=(u+ans)%n+;
R=(v+ans)%n+;
if (L>R) swap(L,R);
ans=query(root[e[L-]],,n,L-,R);
printf("%d\n",ans);
}
}

bzoj3489 A simple rmq problem 可持久化树套树的更多相关文章

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

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

  2. 【kd-tree】bzoj3489 A simple rmq problem

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

  3. BZOJ3489 A simple rmq problem K-D Tree

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

  4. bzoj3489: A simple rmq problem (主席树)

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  5. BZOJ3489: A simple rmq problem

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

  6. BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...

  7. BZOJ 3489 A simple rmq problem(可持久化线段树)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...

  8. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

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

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

随机推荐

  1. 0011 SDK测试方法&ADB语法

    h1.移动云OSS SDK测试方法,包含环境搭建 android  oss sdk 测试方法 1.          搭建测试环境 1.     A ndroid模拟器需要jdk1.6 2.      ...

  2. 【Android开发学习笔记】【第七课】五大布局-上

    概念 Android程序各式各样,依靠的就是布局,先来看看布局都是怎么来的: 白色部分就是我们经常用的几种布局,主要说说介绍下面五大布局 FrameLayout AbsoluteLayout Line ...

  3. Spring整合CXF之发布WebService服务

    今天我们来讲下如何用Spring来整合CXF,来发布WebService服务: 给下官方文档地址:http://cxf.apache.org/docs/writing-a-service-with-s ...

  4. 简述C#中关键字var和dynamic的区别

    C#中关键字var和dynamic的区别如下: 1.var申明的变量必须初始化,dynamic申明的变量无需初始化. 2.var关键字只能在方法内部申明局部变量,dynamic关键字可用于局部变量,字 ...

  5. c#中栈和堆的理解

    之前对栈(stack)和堆(heap)的认识很模糊,今天看了一篇关于堆栈的文章<译文---C#堆VS栈>后,仿佛有种拨开云雾见青天的感觉,当然只是一些浅显的理论的认识,这里做一些简单的记录 ...

  6. LeetCode Find Minimum in Rotated Sorted Array

    原题链接在这里:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ Method 1 就是找到第一个违反升序的值,就 ...

  7. uwsgi选择使用的python版本(转载)

    大概如下 mkdir /data/uwsgi cd /data/uwsgi wget http://projects.unbit.it/downloads/uwsgi-2.0.11.tar.gz ta ...

  8. zookeeper安装和应用场合(名字,配置,锁,队列,集群管理)

    安装和配置详解 本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础,最新的版本可以通过官网http://hadoop.apache.org/zookeeper/ 来获取,Zookee ...

  9. C#高级编程 反射 代码示例

    反射 反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等. 还可以获得每 ...

  10. Android --Android Stuido混淆签名打包

    参考博客:Android studio 使用心得(五)—代码混淆和破解apk 参考博客:Android studio 使用心得(四)---android studio 多渠道打包 参考博客:Andro ...