题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747

题意:有一组序列a[i](1<=i<=N), 让你求所有的mex(l,r), mex(l,r)表示区间[l,r]中最小的未在序列中出现的非负整数。

思路:冥思苦想半天无想法,白做了那么多线段树。 很明显的维护区间问题,容易想到线段树,比较难想到操作。 枚举一个序列的所mex(1,i),mex(2,i)……可以发现序列mex(x,i)是一个单调递增序列,我们需要求得就是所有以x开头的序列和,mex(x,i)(x<=i<=n)。这点确定了就好办了,记录每个位置的数后面最早重复出现的位置next[x],如果无则为设n+1。那么我们就可以发现,当第x个数所对应的序列 mex(x,i)(x<=i<=n)所对应的序列求完之后,删去此位置的数,位置x+1~next[x]-1序列中mex值大于a[x]的都改为a[x],因为a[x]没有了,下一个a[x]还未出现,所以可以证明这样做是正确的。从1到n扫一遍亦求出了所有的mex()。

基本上所有的操作都可以用到线段树。开始没有想到一点的是如何找序列中刚好大于a[x]的位置,并且此位置到next[x]-1赋值为a[x],怎么都没想到log(n)的操作,其实这里依然可以用到线段树,因为序列是单调递增的,另开一个区间维护序列mavv[u]表示区间中最大的mex值,随着询问以及其他操作成段更新即可。

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <sstream>
using namespace std; #define lz 2*u,l,mid
#define rz 2*u+1,mid+1,r
typedef long long lld;
const int maxn=;
int a[maxn], b[maxn], next[maxn];
lld sum[*maxn], mavv[*maxn], flag[*maxn];
map<int,int>mp; void push_up(int u, int l, int r)
{
sum[u]=sum[*u]+sum[*u+];
mavv[u]=mavv[*u+];
} void push_down(int u, int l, int r)
{
int mid=(l+r)>>;
if(flag[u]!=-)
{
flag[*u]=flag[*u+]=flag[u];
mavv[*u]=mavv[*u+]=flag[u];
sum[*u]=(lld)(mid-l+)*flag[u];
sum[*u+]=(lld)(r-mid)*flag[u];
flag[u]=-;
}
} void build(int u, int l, int r)
{
flag[u]=-;
int mid=(l+r)>>;
if(l==r)
{
sum[u]=mavv[u]=b[l];
return ;
}
build(lz);
build(rz);
push_up(u,l,r);
} void Update(int u, int l, int r, int tl, int tr, int val)
{
if(tl>tr) return ;
if(tl<=l&&r<=tr)
{
mavv[u]=val;
sum[u]=(lld)val*(r-l+);
flag[u]=val;
return ;
}
push_down(u,l,r);
int mid=(l+r)>>;
if(tr<=mid) Update(lz,tl,tr,val);
else if(tl>mid) Update(rz,tl,tr,val);
else
{
Update(lz,tl,mid,val);
Update(rz,mid+,tr,val);
}
push_up(u,l,r);
} int find(int u, int l, int r, int tmp)
{
if(l==r) return l;
push_down(u,l,r);
int mid=(l+r)>>;
if(mavv[*u]>tmp) return find(lz,tmp);
else return find(rz,tmp);
} int main()
{
int n;
while(cin >> n,n)
{
for(int i=; i<=n; i++) scanf("%d",a+i);
mp.clear();
for(int i=n; i>=; i--)
{
if(mp[ a[i] ]) next[i]=mp[ a[i] ];
else next[i]=n+;
mp[ a[i] ]=i;
}
mp.clear();
int x=;
for(int i=; i<=n; i++)
{
mp[ a[i] ]=;
while(mp[x]) ++x;
b[i]=x;
}
build(,,n);
lld ans=;
for(int i=; i<=n; i++)
{
ans+=sum[];
if(mavv[]>a[i])
{
int id=find(,,n,a[i]);
Update(,,n,max(id,i+),next[i]-,a[i]);
}
Update(,,n,i,i,);
}
cout << ans <<endl;
}
}

【HDU 4747 Mex】线段数的更多相关文章

  1. hdu 4747 mex 线段树+思维

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

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

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

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

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

  4. HDU 4747 Mex 递推/线段树

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limi ...

  5. HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Problem Description Mex is a function on a set of integers, which is universally used for impartial ...

  6. [HDU 4747] Mex (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 这道题是我去年刚入校队的时候参加网赛的题目. 一年过去了,我依然还是不会做.. 这是我难题计划的 ...

  7. HDU 4747 Mex(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:给出一个数列A.计算所有的mex(i,j)之和.1<=i<=j<=n. ...

  8. HDU 4747 Mex (2013杭州网络赛1010题,线段树)

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

  9. HDU 4747 Mex【线段树上二分+扫描线】

    [题意概述] 一个区间的Mex为这个区间没有出现过的最小自然数,现在给你一个序列,要求求出所有区间的Mex的和. [题解] 扫描线+线段树. 我们在线段树上维护从当前左端点开始的前缀Mex,显然从左到 ...

随机推荐

  1. 廖雪峰js教程笔记 1

    遍历Array可以采用下标循环,遍历Map和Set就无法使用下标.为了统一集合类型,ES6标准引入了新的iterable类型,Array.Map和Set都属于iterable类型. 具有iterabl ...

  2. 记一次小团队Git实践(中)

    对于初学者,从使用上先入手,往往学的最快,并从中汲取教训,再回头更深入的学习,效果尤佳. 安装git 安装git自不必说,mac已经内置了git,linux下一个命令就能搞定,windows下需要下载 ...

  3. TestNg依赖配置基础用法(单一方法依赖)------TestNg依赖详解(一)

    TestNg依赖测试之简单方法依赖,通过dependsOnMethods属性来配置依赖方法 原创文章,版权所有,允许转载,标明出处:http://blog.csdn.net/wanghantong J ...

  4. 我的DbHelper数据操作类

    其实,微软的企业库中有一个非常不错的数据操作类了.但是,不少公司(起码我遇到的几个...),对一些"封装"了些什么的东西不太敢用,虽然我推荐过微软的企业库框架了...但是还是要&q ...

  5. ios开发-载入viewcontroller的几种方式

    Assuming you have storyboard, go to storyboard and give your VC an identifier (inspector), then do: ...

  6. http://www.cnblogs.com/meiCode/p/5896239.html

    http://www.cnblogs.com/meiCode/p/5896239.html

  7. AFNetworking 之于 https 认证

    写在开头: 本来这篇内容准备写在AFNetworking到底做了什么?(三)中的,但是因为我想在三中完结这个系列,碍于篇幅所限.并且这一块内容独立性比较强,所以单独拎出来,写成一篇. 本文从源码的角度 ...

  8. Mac 显示 Finder 隐藏文件

    显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏Mac隐藏文件的命令:defaults writ ...

  9. java中的URLConnection和HttpURLConnection

    URL url = new URL(strUrl); URLConnection con = url.openConnection(); URL url = new URL(strUrl); Http ...

  10. Oracle 查询性能优化实践

      1.索引使用原则   不要对索引使用全模糊,但是 LIKE 'asdf%'是可以的,即不要Contains,可用StartWith 不要对索引进行函数,表达式操作,或者使用is null判断,否则 ...