[bzoj3339]Rmq Problem||[bzoj3585]mex_线段树
Rmq Problem bzoj-3339||mex bzoj-3585
题目大意:给定一个长度为n的数列a,多次讯问区间l,r中最小的不属于集合{$A_l,A_{l+1}...A_r$}的非负整数。
注释:n,q$\le$200,000 ; 0$\le A_i \le$200,000 ; $A_i$均为非负整数,1<=l<=r<=n,l和r均为正整数。
想法:网上很多其他的算法(suika:离线+莫队,WinnieChen:在线权值线段树),我们来聊一聊离线加线段树。
首先,我们将询问离线,按左端点为第一关键字排序。
紧接着,预处理一点东西:暴力求出1~i之间的答案,以及每一个数位置pos的数a[pos]右边第一个等于a[pos]的数,它的位置我们记为nxt[pos]。
然后,我们从左往右扫,对于当前数a[l],对于l+1到nxt[l]-1之间的数都需要进行区间赋值乘a[l],这个操作我们用线段树完成。如果当前节点还是一个被查询区间的左端点的话,我们直接输出右端点对应的mex即可。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <algorithm>
#define lson pos<<1
#define rson pos<<1|1
#define inf 0x7fffffff
using namespace std;
int n,m,k=0;
int a[200005],sg[200005],ans[200005],next[200005],last[200005];
int ls[600005],rs[600005],mn[600005];
bool mark[200001];
struct data{int l,r,id;}q[200005];
bool cmp(data a,data b)
{return a.l<b.l;}
void build(int l,int r,int pos)
{
ls[pos]=l;
rs[pos]=r;
mn[pos]=inf;
if(l==r)
{
mn[pos]=sg[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,lson);build(mid+1,r,rson);
}
void pushdown(int pos)
{
int l=ls[pos],r=rs[pos];
if(l==r)return;
mn[lson]=min(mn[pos],mn[lson]);
mn[rson]=min(mn[pos],mn[rson]);
}
int ask(int pos,int x)
{
if(mn[pos]!=inf)pushdown(pos);
int l=ls[pos],r=rs[pos];
if(l==r)return mn[pos];
int mid=(l+r)>>1;
if(x<=mid)return ask(lson,x);
return ask(rson,x);
}
void update(int pos,int x,int y,int val)
{
if(mn[pos]!=inf)pushdown(pos);
int l=ls[pos],r=rs[pos];
if(l==x&&y==r){mn[pos]=min(mn[pos],val);return;}
int mid=(l+r)>>1;
if(y<=mid)update(lson,x,y,val);
else if(x>mid)update(rson,x,y,val);
else
{
update(lson,x,mid,val);
update(rson,mid+1,y,val);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
mark[a[i]]=1;
if(a[i]==k)
while(mark[k])k++;
sg[i]=k;
}
build(1,n,1);
for(int i=n;i>0;i--)
next[i]=last[a[i]],last[a[i]]=i;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
int now=1;
for(int i=1;i<=m;i++)
{
while(now<q[i].l)
{
if(!next[now])next[now]=n+1;
update(1,now,next[now]-1,a[now]);
now++;
}
ans[q[i].id]=ask(1,q[i].r);
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}
小结:对着hzwer学长写的动态开点,感觉爆炸。注意pushdown的时候要记得删除之前的标记。
[bzoj3339]Rmq Problem||[bzoj3585]mex_线段树的更多相关文章
- CF803G-Periodic RMQ Problem【离散化,线段树,ST表】
正题 题目链接:https://www.luogu.com.cn/problem/CF803G 题目大意 一个长度为\(n\)的序列\(a\)复制\(k\)份连接,要求支持 区间赋值 区间查询最小值 ...
- BZOJ 3489 A simple rmq problem(可持久化线段树)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489 题意:一个数列.每次询问一个区间内出现一次的最大的数字是多少. 思路:设la ...
- hihocode 1077 : RMQ问题再临-线段树
#1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...
- Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)
#1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...
- poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=3468 线段树模板 要背下此模板 线段树 #include <iostream> #include <vector> ...
- 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...
- [BZOJ3339] Rmq Problem(线段树)
传送门 这个题的方法好像很多啊 1.莫队暴力 2.线段树 + 离线处理 先预处理出sg[i]表示前i个数的sg值,next[i]表示i的下一位置在哪里,如果后面再没有i,那么next[i] = n + ...
- BZOJ3339 Rmq Problem
[bzoj3339]Rmq Problem Description Input Output Sample Input 7 5 0 2 1 0 1 3 2 1 3 2 3 1 4 3 6 2 7 Sa ...
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
随机推荐
- npm 与 package.json 快速入门教程
npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...
- php安全过滤类
/*ansic码-Url码表: http://www.w3school.com.cn/tags/html_ref_urlencode.html ---------------------------- ...
- Unity - 简单实例化的应用
项目描述:每帧实例化一个随机颜色的物体(Cube),坐标在某范围内随机:且物体每帧都会缩小,当缩小到一定的尺寸时,就销毁物体 代码描述: public class CubeSpawner : Mono ...
- Java基础学习经验分享
很多人学习Java,尤其是自学的人,在学习的过程中会遇到各种各样的问题以及难点,有时候卡在一个点上可能需要很长时间,因为你在自学的过程中不知道如何去掌握和灵活运用以及该注意的点.下面我整理了新手学习可 ...
- javascript 处理链接的多种方式
在页面中的链接除了常规的方式以外,如果使用javascript,还有很多种方式,下面是一些使用javascript,打开链接的几种方式: 1.使用window的open方法打开链接,这里可是在制定页面 ...
- 使用Visual Studio Code + Node.js搭建TypeScript开发环境
Visual Studio Code搭建Typescript开发环境 —— 相关文章: http://www.cnblogs.com/sunjie9606/p/5945540.html [注意:这里仅 ...
- Sublime Text Version 3.0,Build3143注册码
1.打开sublime text软件2.Help->Enter License3.复制以下BEGIN LICENSE和END LICENSE之间的部分,粘贴进去.(注意:不要复制BEGIN LI ...
- c的二级指针
----"c 语言的精华在于指针的灵活性.学好指针的目的在于尽可能少的使用指针." 在敲binary search tree(二叉查找树),遇到了问题.在删除的时候,如果删除的是r ...
- 开源业务规则引擎JBoss Drools
Drools 是什么? 规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策.接受数据输入,解释业务规则,并根据业务规 ...
- IOS7升级攻略
1) Select the main view, set the background color to black (or whatever color you want the status ba ...