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_线段树的更多相关文章

  1. CF803G-Periodic RMQ Problem【离散化,线段树,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/CF803G 题目大意 一个长度为\(n\)的序列\(a\)复制\(k\)份连接,要求支持 区间赋值 区间查询最小值 ...

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

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

  3. hihocode 1077 : RMQ问题再临-线段树

    #1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...

  4. Hihocoder #1077 : RMQ问题再临-线段树(线段树:结构体建树+更新叶子往上+查询+巧妙使用father[]+线段树数组要开大4倍 *【模板】)

    #1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...

  5. poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=3468 线段树模板 要背下此模板 线段树 #include <iostream> #include <vector> ...

  6. 2018 ACMICPC上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 H - A Simple Problem with Integers (线段树,循环节) 链接:https://ac.nowcoder.co ...

  7. [BZOJ3339] Rmq Problem(线段树)

    传送门 这个题的方法好像很多啊 1.莫队暴力 2.线段树 + 离线处理 先预处理出sg[i]表示前i个数的sg值,next[i]表示i的下一位置在哪里,如果后面再没有i,那么next[i] = n + ...

  8. 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 ...

  9. BZOJ3489 A simple rmq problem 【可持久化树套树】*

    BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...

随机推荐

  1. Balanced Lineup(线段树)

    http://poj.org/problem?id=3264 题意:n个数,q个询问,输出[l,r]中最大值与最小值的差. #include <stdio.h> #include < ...

  2. [Apple开发者帐户帮助]六、配置应用服务(5.2)推送通知(APN):使用TLS证书与APN通信

    您的通知服务器可以使用TLS证书与Apple推送通知服务(APN)通信. 首先在开发者帐户中启用推送通知.接下来生成适用于开发和生产环境的APNs客户端TLS证书.然后从Mac导出客户端TLS标识并将 ...

  3. Django day27 认证组件,权限组件()

    一:认证组件 1.写一个类 class LoginAuth(): # 函数名一定要叫authenticate,接收必须两个参数,第二个参数是request对象 def authenticate(sel ...

  4. sql 查询出当天记录数据

    select updatetime,NewComment,HistoryID,sum(1) over(partition by UpdateTime) from LPProjectHistoryord ...

  5. dubbo+zookeeper下生产者和消费者配置(基于springboot开发)

    一.总共分为三个目录: dubbo-api      服务的接口用于对接客户端和服务端 dubbo-client     客户端配置文件为:consumer.xml dubbo-service  服务 ...

  6. 解决gradle project refresh failed: protocol family unavailable问题的几种方法

    Android Studio从版本1.5更新到2.1之后,打开Android Studio一直提示: gradle project refresh failed: protocol family un ...

  7. 如何查看jdk的版本

    (1)WINDOWS环境下 实验环境:WIN7 64bit 操作指令:cmd命令下输入“java -version” 参考如下:JDK1.7 (2).LINUX环境下 实验环境:CentOS 5.6 ...

  8. js基础---元素操作时字符串拼接

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. [转]使用gdb调试异常

    有时程序中有未捕获的异常会导致程序异常的行为甚至导致程序的直接退出. 这对服务器程序来说是不可接受的. 可以使用gdb的catch命令来帮助我们调试异常. 使用gdb捕获异常的扔出点(相当于在扔出异常 ...

  10. GNSS数据下载网站

    Bernese 数据表文件下载 rinex文件下载 ftp://nfs.kasi.re.kr DCB.ION文件ftp://ftp.unibe.ch/AIUB/CODE/ 下载5.0更新文件 ftp: ...