先预处理出两个个数组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. PHP数据库基础

    PHP数据库基础: 1.varchar:字符串,用于姓名班级,地址等,地址一般长50,姓名长20 2.int:整数,用于成绩,序号等 3.float:小数 4.bit:布尔型,用于性别等 5.时间也用 ...

  2. Nginx+Django+Uwsgi+php

    在FreeBSD结合Nginx和FastCGI简单配置Django和PHP  http://blog.chinaunix.net/uid-11131943-id-3031767.html Nginx+ ...

  3. HBase学习笔记-高级(一)

    HBase1. hbase.id记录了集群的唯一标识:hbase.version记录了文件格式的版本号2. split和.corrupt目录在日志分裂过程中使用,以便保存一些中间结果和损坏的日志在表目 ...

  4. html5学习测试

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Caused by: java.lang.OutOfMemoryError: PermGen space.

    现在eclipse需要加载4个项目同时运行了,所以当服务启动的时候,出现Caused by: java.lang.OutOfMemoryError: PermGen space.空间不足错误,我说一下 ...

  6. Android笔记:java 中的数组

    在与嵌入式设备通讯的过程中使用的socket通讯 获取的字节流,通常转换为字节数组,需要根据协议将字节数组拆分.对于有规律的重复拆分可以使用,由于java中不能像c中直接进行内存操作例如使用struc ...

  7. 在zendstudio中添加注释

    /** * * * @access public * @param string $cat_id 分类查询字符串 * @return string */ 然后在function之前的一行打上/**然后 ...

  8. 配置SQL Server Session方法

    以下过程是在Win 2003 SP2 + IIS 6.0, ASP.NET 2.0, SQL Server 2005下进行的. 1. 安装Session数据库到Framework目录 C:\WINDO ...

  9. Mybatis的分页插件PageHelper

    Mybatis的分页插件PageHelper 项目地址:http://git.oschina.net/free/Mybatis_PageHelper  文档地址:http://git.oschina. ...

  10. 通过sqlserver日志恢复误删除的数据

     如果你已经急的焦头烂额,看到这篇文章的时候,请你换个坐姿,深呼吸几次,静下心来将这篇文章读完,也许你的问题迎刃而解. 我遇到的情况是这样的,网站被植入木马,盗取了我的web.config文件,web ...