[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]之间找到一个在这个区间里只出现过一 ...
随机推荐
- tinymce 出现 Uncaught (in promise) TypeError: ae(...).createObjectURL is not a function
需要引入两个JS文件:jQuery.tinymce.min.js 和 tinymce.min.js <script type="text/javascript" src=&q ...
- java—容器学习笔记
一:迭代器 刚开始学容器,做了个简单的练习题.. import java.util.ArrayList; import java.util.Collection; import java.util.I ...
- Mysql中date,time,datetime,timestamp的区别
区别: timestamp:时间戳.北京时间1970年01月01日08时00分00秒 起至现在的总秒数. datetime:带时分秒的完整时间,例如:1970-01-01 10:00:00 date: ...
- 一款超好用的第三方评论插件--Gitalk
一,使用Gitalk的背景: 1.最近在做一个基于Java的个人博客系统,已经基本完工了,突然发现怎么没有评论的操作,如果再从头开始从数据库开始写的话,花费的代价有点大,于是乎我就在网上寻找一款适合我 ...
- assistant: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by
[oracle@oracledb button]$ assistantassistant: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' no ...
- 简单认识http协议
1.什么是TCP/IP 如果要了解一个人,可以从他归属的集体聊起来.我们的HTTP协议就属于TCP/IP协议家族中的一员,了解HTTP协议再整个网络流程中的地位,也能更加充分的理解HTTP协议. 要 ...
- Elasticsearch之CURL命令的UPDATE
对于,Elasticsearch之CURL命令的UPDATE包括局部更新和全部更新.可以去看我写的另一篇博客. Elasticsearch之更新(全部更新和局部更新) 总结: ES全部更新,使用PUT ...
- B树、B+树、红黑树、AVL树比较
B树是为了提高磁盘或外部存储设备查找效率而产生的一种多路平衡查找树. B+树为B树的变形结构,用于大多数数据库或文件系统的存储而设计. B树相对于红黑树的区别 在大规模数据存储的时候,红黑树往往出现由 ...
- 关于debug.keystore文件用法以及错误处理
在开发过程中需要频繁的为测试的同事签名apk,非常很麻烦,把默认debug.keystore文件替换成发布用(生产环境)的签名文件,不用频繁地签名apk文件了. 如果直接使用生产keysto ...
- SV creation order
SystemVerilog Instance Worlds When generating an UVM testbench and in particular the DUT - testbench ...