bzoj3489 A simple rmq problem 可持久化树套树
先预处理出两个个数组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 可持久化树套树的更多相关文章
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
- 【kd-tree】bzoj3489 A simple rmq problem
Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre ...
- BZOJ3489 A simple rmq problem K-D Tree
传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...
- bzoj3489: A simple rmq problem (主席树)
//========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/ 转载要声明! //=============== ...
- BZOJ3489: A simple rmq problem
设$i$的前驱为$p_i$,后继为$q_i$,把询问看成点$(L,R)$,有贡献的$i$满足$L\in(p_i,i]$且$R\in[i,q_i)$,询问的就是覆盖这个点的矩形的最大值.那么可以用可持久 ...
- BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...
- BZOJ 3489 A simple rmq problem(可持久化线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...
- 【bzoj3489】 A simple rmq problem k-d树
由于某些原因,我先打了一个错误的树套树,后来打起了$k-d$.接着因不明原因在思路上被卡了很久,在今天中午蹲坑时恍然大悟...... 对于一个数字$a_i$,我们可以用一组三维坐标$(i,pre,nx ...
随机推荐
- Docker Device Mapper 使用 direct-lvm
一.Device Mapper: loop-lvm 默认 CentOS7 下 Docker 使用的 Device Mapper 设备默认使用 loopback 设备,后端为自动生成的稀疏文件,如下 ...
- 获取枚举Description 属性
/// <summary> /// 获取枚举变量值的 Description 属性 /// </summary> /// <param name="obj&qu ...
- Linux QtCreator设置mingw编译器生成windows程序
Qt跨平台,那必须在Linux平台编译一个可以在windows下运行的Qt程序才行,当然还得和QtCreator环境弄在一起才行. 工作环境:Centos 7 yum install qt5-qt* ...
- C#中Dynamic关键字
dynamic关键字和动态语言运行时(DLR)是.Net 4.0中新增的功能. 什么是"动态"? 编程语言有时可以划分为静态类型化语言和动态类型化语言.C#和Java经常被认为是静 ...
- jade反编译
安装html2jade npm install html2jade -g 反编译,默认输出同名jade html2jade test2.html 反编译为其他文件名 html2jade test2.h ...
- oracle 表查询二
1.使用逻辑操作符号问题:查询工资高于500或者是岗位为manager的雇员,同时还要满足他们的姓名首字母为大写的J?select * from emp where (sal > 500 or ...
- (转帖) java内存分配分析/栈内存、堆内存
http://blog.csdn.net/qh_java/article/details/9084091
- Miscellaneous--Tech
1. Questions: 1)EF.2)MVC/MVP/MVVM.3)page lifecyle. preInit,Init,InitCompleted,preLoad,Load,LoadCompl ...
- JVM底层又是如何实现synchronized的
目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronized与Loc ...
- LeetCode Binary Search Tree Iterator
原题链接在这里:https://leetcode.com/problems/binary-search-tree-iterator/ Implement an iterator over a bina ...