题目链接

当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++。


\(Description\)

给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数。强制在线。

\(Solution\)

我也不知道该怎么说,反正就是预处理 建主席树,套堆/set,树i存l为i,r为[i,n]的答案(这样就是在某棵树上单点查maxv了)。

处理好最初的树,就可以利用主席树根据前缀建树的性质,每个点i的建树只需要处理i位置。

那么最初的树就是将所有的数在区间[第一次出现位置,nxt[]-1]中加入这个数。

当左端点i移动时,A[i-1]的贡献没了,要删掉;但是如果A[i-1]在后面出现,则还要在[nxt[A[i-1]],nxt[nxt[A[i-1]]]-1]上加入A[i-1]。(A[i]已经处理了,要么在建最初树时要么在先前建的树中)

也不是每棵树每个节点都套堆,堆只需要帮助建主席树时加加删删(还是利用前缀),要用的只是根据堆得到的每个节点的maxv[],所以堆还是4n大就可以。。

和CF那题不同的是这题固定l更方便,那题固定r好些。所以只需要nxt(和最靠前的一个las用来建最初的树)。

第一次主席树区间修改。。在信息覆盖当前区间时直接给节点赋值,return;查询单点时加上沿路节点的mx[](标记永久化)。

注意新建节点时copy x的mx[]。因为每次删除是完全删除上一次的加入,so在未递归到完全覆盖区间前copy mx是对的?真这样麻烦吗。。以后是不是该乖乖写Update()。。


询问的限制条件可以看成三个维度,即在某三维空间内找权值最大的点,可以用K-D Tree。出题人说这不应是正解,可以卡,只是数据问题跑的比主席树快。。可以看这儿

不过还是K-D Tree更好的应用吧,不想看了,先放着。。

K-D Tree:https://blog.csdn.net/FromATP/article/details/61198101


代码参考(chao)自:https://blog.csdn.net/u014609452/article/details/51396271。


非强制在线可以直接线段树+排序扫描线做,有个简化版的题见这儿


//147544kb	9488ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1e5+5; int n,Q,A[N],las[N],nxt[N],rcnt,root[N*3],pos[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Tree//Persistent Segment Tree
{
#define S N*100//我也不知道这样搞区间修改的主席树会有多少节点(2个log?)
#define lson son[x][0]
#define rson son[x][1]
#define ToL l,m,rt<<1
#define ToR m+1,r,rt<<1|1
struct Heap
{
std::priority_queue<int> h,d;
inline void Insert(int x) {h.push(x);}
inline void Delete(int x) {d.push(x);}
inline void Maintain(){
while(!h.empty()&&!d.empty()&&h.top()==d.top()) h.pop(),d.pop();
}
inline int Top(){
Maintain(); return h.empty()?0:h.top();
}
}hp[N<<2];
int tot,son[S][2],mx[S]; // inline void Update(int x){//Update没啥用啊 又不用区间信息
// mx[x]=std::max(mx[lson],mx[rson]);
// }
void Insert(int &y,int x,int l,int r,int rt,int L,int R,int v)//rt:一般线段树的节点 存储堆
{
y=++tot;
if(L<=l && r<=R){
hp[rt].Insert(v), mx[y]=hp[rt].Top(), son[y][0]=lson, son[y][1]=rson;
return ;
}
int m=l+r>>1; mx[y]=mx[x];//!
if(L<=m)
if(m<R) Insert(son[y][0],lson,ToL,L,R,v), Insert(son[y][1],rson,ToR,L,R,v);
else son[y][1]=rson, Insert(son[y][0],lson,ToL,L,R,v);
else son[y][0]=lson, Insert(son[y][1],rson,ToR,L,R,v);
}
void Delete(int &y,int x,int l,int r,int rt,int L,int R,int v)
{
y=++tot;
if(L<=l && r<=R){
hp[rt].Delete(v), mx[y]=hp[rt].Top(), son[y][0]=lson, son[y][1]=rson;
return;
}
int m=l+r>>1; mx[y]=mx[x];//!
if(L<=m)
if(m<R) Delete(son[y][0],lson,ToL,L,R,v), Delete(son[y][1],rson,ToR,L,R,v);
else son[y][1]=rson, Delete(son[y][0],lson,ToL,L,R,v);
else son[y][0]=lson, Delete(son[y][1],rson,ToR,L,R,v);
}
int Query(int x,int l,int r,int pos)
{
if(!x) return 0;//这个没啥用啊...
if(l==r) return mx[x];
int m=l+r>>1;
if(pos<=m) return std::max(mx[x],Query(lson,l,m,pos));
else return std::max(mx[x],Query(rson,m+1,r,pos));
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
n=read(), Q=read();
for(int i=1; i<=n; ++i) A[i]=read();
for(int i=1; i<=n; ++i) las[i]=n+1;
for(int i=n; i; --i) nxt[i]=las[A[i]], las[A[i]]=i;
for(int i=n; i; --i)//直接枚举值域建树就可以啊 话说倒着插入堆会更快吗
if(las[i]<=n) T.Insert(root[rcnt],root[rcnt++],1,n,1,las[i],nxt[las[i]]-1,i);//参数顺序
pos[1]=root[rcnt];//root[rcnt] not rcnt→_→
for(int i=1; i<n; ++i)
{
T.Delete(root[rcnt],root[rcnt++],1,n,1,i,nxt[i]-1,A[i]);
if(nxt[i]<=n)
T.Insert(root[rcnt],root[rcnt++],1,n,1,nxt[i],nxt[nxt[i]]-1,A[i]);
pos[i+1]=root[rcnt];
}
for(int ans=0,i=1,l,r; i<=Q; ++i)
{
l=(read()+ans)%n+1, r=(read()+ans)%n+1;
if(l>r) std::swap(l,r);//l>r&&(std::swap(l,r),1);
printf("%d\n",ans=T.Query(pos[l],1,n,r));
}
return 0;
}

BZOJ.3489.A simple rmq problem(主席树 Heap)的更多相关文章

  1. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  2. bzoj 3489 A simple rmq problem —— 主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  3. bzoj 3489: A simple rmq problem k-d树思想大暴力

    3489: A simple rmq problem Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 551  Solved: 170[Submit][ ...

  4. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  5. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

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

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

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

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

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

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

  9. bzoj 3585: mex && 3339: Rmq Problem -- 主席树

    3585: mex Time Limit: 20 Sec  Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区 ...

随机推荐

  1. SQL Server 2000事务复制问题

    2000现在用的估计不多了,把之前收集的一些复制问题整理发布出来.可能都是些很白很二的问题,但人总是由最初的无知不断成长●-● SQL Server 2000事务复制问题服务器A(发布) 服务器B(分 ...

  2. jquery ajax complete 方法

    jquery ajax var ajaxTimeoutTest = $.ajax({ url:'',  //请求的URL timeout : 1000, //超时时间设置,单位毫秒 type : 'g ...

  3. [转]CMake快速入门教程:实战

    转自http://blog.csdn.net/ljt20061908/article/details/11736713 0. 前言    一个多月前,由于工程项目的需要,匆匆的学习了一下cmake的使 ...

  4. Treats for the Cows 区间DP POJ 3186

    题目来源:http://poj.org/problem?id=3186 (http://www.fjutacm.com/Problem.jsp?pid=1389) /** 题目意思: 约翰经常给产奶量 ...

  5. SpringMVC控制器 跳转到jsp页面 css img js等文件不起作用 不显示

    今天在SpringMVC转发页面的时候发现跳转页面确实成功,但是JS,CSS等静态资源不起作用: 控制层代码: /** * 转发到查看培养方案详情的页面 * @return */ @RequestMa ...

  6. Motan

    https://github.com/weibocom/motan/wiki/zh_userguide http://www.cnblogs.com/mantu/p/5885996.html(源码分析 ...

  7. 【h5标签转小程序标签】小程序使用wxParse解析html教程

    一.先下载所需文件,下载地址:https://pan.baidu.com/s/1umZO9uI24zUTRd7VqaWbAg  ,下载完毕后会得到一个wxParse文件夹,后面会用到: 二.先拷贝cs ...

  8. 浅谈js设计模式之单例模式

    单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如线程池.全局缓存.浏览器中的 window 对象等.在 JavaS ...

  9. makefile特殊符号介绍

    http://blog.chinaunix.net/uid-20564848-id-217918.html makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$ ...

  10. Spring框架的基本使用(IOC部分)

    Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. Spring的好处 1.方便解耦,简化开发: Spring就是一个大工厂,专门负责生成Bean,可以将所有对象创建和依赖关 ...