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 ...
随机推荐
- Qt中单例模式的实现(4种方法)
最简单的写法: 12345 static MyClass* MyClass::Instance(){ static MyClass inst; return &inst;} 过去很长一段时间一 ...
- ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click 'Restart'
ADB not responding. If you'd like to retry, then please manually kill "adb.exe" and click ...
- ADO.NET中主要对象
ADO.NET是什么? ADO.NET是.Net平台提供和数据库交互的类库集,我们可以通过它对SQLSERVER,XML,Oracle等这样的数据源进行访问. 应用程序可以使用ADO.NET链接到数据 ...
- 【android学习1】:安装MySQL启动服务失败解决方法
最近需要用到MySQL,从官网上下载了一个安装文件,但是安装时一直弹出如下提示信息: Configuration of MySQL Server 5.7 is taking longer than e ...
- css spprite应用
(一)实现简单的淘宝带图标侧边栏效果 <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- Using Change Management and Change Control Within a Project
In any project, change is inevitable whether it comes from within the project or from external sourc ...
- iOS开发中 在MRC中让某些类使用ARC编译 或者相反
如果你的工程是MRC 想让某些类使用ARC进行编译的话 那么需要在Build Phases中Complile Sourse 把该类后面 写上如下命令:-fobjc-arc 反之 写上如下命令:-fn ...
- miaov- 自动生成正V反V大于号V小于号V楼梯等图案
1. 核心:控制 数量的长度-1-i的位置,是放在left上还是top上?是放在前面还是后面! <!DOCTYPE html> <html lang="en"&g ...
- A股中为什么有涨幅超过10%的
在A股规定涨跌幅10%的正常交易日中,某些股票的涨跌幅却超出或没达到10%的,原因是因为A股的交易中最小的价格“申报单位为0.01元”,就是说某些股票不管什么价格都不会刚刚好是10%,它只能“取最近于 ...
- OpenGl的glMatrixMode()函数理解
glMatrixMode()函数的参数,这个函数其实就是对接下来要做什么进行一下声明,也就是在要做下一步之前告诉计算机我要对“什么”进行操作了,这个“什么”在glMatrixMode的“()”里的选项 ...