题目大意:给一个长度为n的整数序列,定义mex(i,j)表示区间[i,j]中没有出现过的最小非负整数,求sigma(mex(i,j)),即序列中所有连续非空子区间的mex之和。

题目分析:

answer=mex(1,1)+mex(1,2)...mex(1,n)
+ mex(2,2)...mex(2,n)
.
.
.
+ mex(n,n)。

  初始时,用线段树的叶子节点维护mex(1,i),将a(1)从序列中拿去后,将叶子节点的维护信息更新为mex(2,i),以此类推...没更新一次,便求一次区间和,总和即为答案。

  当拿掉a(i)后,只有a(k)以前的mex(i+1,j)将会受到影响,其中k>i并且a(i)=a(k)。

  当i+1<=j<k时,如果mex(i,j)>a(i),那么mex(i+1,j)=a(i),否则mex(i+1,j)=mex(i,j)。显然,当 i 固定时,mex(i,j)关于 j 单调不减。所以,mex(i,j)>a(i)的将会是一段区间。

代码如下:

# include<bits/stdc++.h>
using namespace std;
# define LL long long
# define mid (l+(r-l)/2) const int N=200000; int a[N+5];
int mex[N+5];
int nxt[N+5];
LL tr[N*4+5];
LL lazy[N*4+5];
int maxn[N*4+5]; inline void getMex(int n)
{
map<int,int>mp;
map<int,int>f;
fill(nxt,nxt+1+n,n+1);
int m=0;
for(int i=1;i<=n;++i){
mp[a[i]]=1;
while(mp[m]) ++m;
mex[i]=m;
if(f[a[i]])
nxt[f[a[i]]]=i;
f[a[i]]=i;
}
} inline void pushUp(int rt)
{
tr[rt]=tr[rt<<1]+tr[rt<<1|1];
maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
} inline void pushDown(int rt,int l,int r)
{
if(lazy[rt]!=-1){
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
maxn[rt<<1]=maxn[rt<<1|1]=lazy[rt];
tr[rt<<1]=lazy[rt]*(LL)(mid-l+1);
tr[rt<<1|1]=lazy[rt]*(LL)(r-mid);
lazy[rt]=-1;
}
} inline void build(int rt,int l,int r)
{
lazy[rt]=-1;
if(l==r){
tr[rt]=mex[l];
maxn[rt]=mex[l];
}else{
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushUp(rt);
}
} inline int query_up(int rt,int l,int r,int L,int R,int x)
{
if(l==r){
if(tr[rt]<x) return 0;
return l;
}
pushDown(rt,l,r);
if(L<=mid&&x<maxn[rt<<1]){
int k=query_up(rt<<1,l,mid,L,R,x);
if(k>0) return k;
}
if(R>mid&&x<maxn[rt<<1|1]){
int k=query_up(rt<<1|1,mid+1,r,L,R,x);
if(k>0) return k;
}
return 0;
} inline void update(int rt,int l,int r,int L,int R,int x)
{
if(L<=l&&r<=R){
lazy[rt]=x;
tr[rt]=(LL)x*(LL)(r-l+1);
maxn[rt]=x;
}else{
pushDown(rt,l,r);
if(L<=mid) update(rt<<1,l,mid,L,R,x);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,x);
pushUp(rt);
}
} inline LL query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return tr[rt];
pushDown(rt,l,r);
LL res=0;
if(L<=mid) res+=query(rt<<1,l,mid,L,R);
if(R>mid) res+=query(rt<<1|1,mid+1,r,L,R);
return res;
} int main()
{
int n;
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;++i) scanf("%d",a+i);
getMex(n);
build(1,1,n);
LL ans=query(1,1,n,1,n);
for(int i=1;i<n;++i){
int p=query_up(1,1,n,i+1,nxt[i]-1,a[i]);
if(p>0) update(1,1,n,p,nxt[i]-1,a[i]);
ans+=query(1,1,n,i+1,n);
}
printf("%lld\n",ans);
}
return 0;
}

  

HDU-4747 Mex(线段树区间更新)的更多相关文章

  1. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  2. hdu 4747 mex 线段树+思维

    http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...

  3. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  4. HDU 3308 LCIS 线段树区间更新

    最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛  ,小媛姐.这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667 Hotel 这个题目 ...

  5. hdu 1698(线段树区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. hdu 4747 Mex( 线段树? 不,区间处理就行(dp?))

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  7. HDU 1556【线段树区间更新】

    这篇lazy讲的很棒: https://www.douban.com/note/273509745/ if(tree[rt].l == l && r == tree[rt].r) 这里 ...

  8. HDU 4747 Mex ( 线段树好题 + 思路 )

    参考:http://www.cnblogs.com/oyking/p/3323306.html 相当不错的思路,膜拜之~ 个人理解改日补充. #include <cstdio> #incl ...

  9. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  10. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

随机推荐

  1. Program A - 暴力求解

    Description   Write a program that finds and displays all pairs of 5-digit numbers that between them ...

  2. javaNIO是什么?由那几部分组成?各部分的作用。

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Sel ...

  3. 内部类中class声明地方不同,效果不一样

    1.一个声明在类中,一个声明在类的方法中.在类中的方法中声明内部类,其方法中的内部类调用 内部类外中的变量,变量必须final class Outter{ int x1 = 0; public voi ...

  4. AutoCAD ObjectARX(VC)开发基础与实例教程2014版光盘镜像

    AutoCAD ObjectARX(VC)开发基础与实例教程2014,最新版,光盘镜像 作者:张帆 朱文俊 编著 出版社:中国电力出版社 出版时间:2014年6月 点击一下

  5. Errors

    Errors running builder 'Android Resource Manager' on project 'Demo'. java.lang.NullPointerException ...

  6. 二、XML约束

    XML约束有dtd约束和Schema约束两种 dtd约束:可以在xml内部写dtd约束也可以在xml中引用外部dtd文件 book.dtd<!ELEMENT 书架 (书+)>    < ...

  7. (spring-第2回【IoC基础篇】)Spring的Schema,基于XML的配置

    要深入了解Spring机制,首先需要知道Spring是怎样在IoC容器中装配Bean的.而了解这一点的前提是,要搞清楚Spring基于Schema的Xml配置方案. 在深入了解之前,必须要先明白几个标 ...

  8. iOS提交AppStore被拒原因

    1. Terms and conditions(法律与条款) 1.1 As a developer of applications for the App Store you are bound by ...

  9. Asp.net操作Excel----NPOI!!!!1

    前言 Asp.net操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,使 用NPOI能够帮助开发者在没有安装微软Office的情况下读写Off ...

  10. JNI c++ 调用 java

    ----------------------------------------------c++--------------------------------------- #include &q ...