先预处理出两个个数组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. 数据库留言板例题:session和cookie区别

    session和cookie区别: <?php session_start(); //session_start();必须写在所有的php代码前边 ?> <!DOCTYPE html ...

  2. Selinux在HTTP+PHP服务中的安全权限修改

    在PHP用使用fopen的写入功能实,常会遇到诸如: PHP Warning:  fopen(file): failed to open stream: Permission denied in (f ...

  3. python标准库介绍

    操作系统接口 os模块提供了不少与操作系统相关联的函数. >>> import os >>> os.getcwd() # 返回当前的工作目录 'C:\\Python ...

  4. centos apache安装和设置

    分类: LINUX 安装方式:yum install httpdyum install mysql-serveryum install phpyum install php-mysql 一.WEB服务 ...

  5. Redis学习笔记(1)-Key

    package cn.com; import java.text.ParseException; import java.util.List; import java.util.Set; import ...

  6. [LeetCode] Divide Two Integers( bit + 二分法 )

    Divide two integers without using multiplication, division and mod operator. 常常出现大的负数,无法用abs()转换成正数的 ...

  7. cf708B. Recover the String---(构造法)

    题目链接:http://codeforces.com/problemset/problem/708/B 意思是给出四个参数 a00表01串中00对的数量 a01表01串中01对的数量 a10表01串中 ...

  8. JMeter学习-001-JMeter初识

    Apache JMeter是Apache组织开发的基于Java的开源压力测试工具(个人发现也可用于接口测试).用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于 ...

  9. git 项目初始化

    1.在git服务器界面右上角“+” .create  new  project ,写上项目名字生成一个新的组 2.如果机器第一次与git 建立连接,需要让机器生成一个id_rsa和id_rsa.pub ...

  10. Java 实现网站当前在线用户统计

    1. import java.util.HashSet; import javax.servlet.ServletContext; import javax.servlet.http.HttpSess ...