【HDU 4747 Mex】线段数
题目链接: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】线段数的更多相关文章
- hdu 4747 mex 线段树+思维
http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...
- hdu 4747 Mex( 线段树? 不,区间处理就行(dp?))
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 4747 Mex ( 线段树好题 + 思路 )
参考:http://www.cnblogs.com/oyking/p/3323306.html 相当不错的思路,膜拜之~ 个人理解改日补充. #include <cstdio> #incl ...
- HDU 4747 Mex 递推/线段树
题目链接: acm.hdu.edu.cn/showproblem.php?pid=4747 Mex Time Limit: 15000/5000 MS (Java/Others)Memory Limi ...
- 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 ...
- [HDU 4747] Mex (线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 这道题是我去年刚入校队的时候参加网赛的题目. 一年过去了,我依然还是不会做.. 这是我难题计划的 ...
- HDU 4747 Mex(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:给出一个数列A.计算所有的mex(i,j)之和.1<=i<=j<=n. ...
- HDU 4747 Mex (2013杭州网络赛1010题,线段树)
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 4747 Mex【线段树上二分+扫描线】
[题意概述] 一个区间的Mex为这个区间没有出现过的最小自然数,现在给你一个序列,要求求出所有区间的Mex的和. [题解] 扫描线+线段树. 我们在线段树上维护从当前左端点开始的前缀Mex,显然从左到 ...
随机推荐
- filter应用案例二:权限控制
filter可以用来进行权限控制,比如admin文件夹下的文件只允许管理员进入,那么,可以给admin文件夹加上一个过滤器: 简单代码示例: import java.io.IOException; i ...
- PS切图的几种方式
方法一 点击图层右键-->导出为 导出需要的格式与大小 方法二 选择多个图层右键--->快速导出为PNG(导出的名字就是图层名字) 方法三
- JQuery解析json数据
<script> var data ="{" + "root:[" + "{name:'1',value:'0'}," + &q ...
- javascript优化--12模式(设计模式)03
观察者模式 通过创建一个可观察的对象,当发生一个感兴趣的事件时将该事件通告给所有观察者,从而形成松散的耦合 订阅杂志 //发布者对象 var publisher = { subscribers: { ...
- jquery mousewheel
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js&quo ...
- [bzoj3813]奇数园
仿佛现在已经完成了做题之前先开个坑的习惯,也许是为了逼迫自己去刷一些神题吧...然并卵,该剩的好多坑还是剩着呢. [bzoj3813]一道线段树好题.已经把数论忘光光了. 欧几里德算法 扩展欧几里德算 ...
- 当 NSDictionary 遇见 nil
Demo project: NSDictionary-NilSafe 问题 相信用 Objective-C 开发 iOS 应用的人对下面的 crash 不会陌生: *** -[__NSPlacehol ...
- linqPad快速学习LINQ(含视频)
在这里我向大家推荐的一个具是LinqPad有了这个工具并熟练使用就可以很快学习并掌握linq 安装步骤: 使用LINQPad可以很方便的调试linq以及lambda表达式.其中自带了linq以及F#简 ...
- 【转】如果成为一个牛比的BI售前
转自:天善智能 没有最厉害,只有更厉害啊.也没有一定哪儿厉害,会因人定制各有不同啊.打个比方,如果你长得很庄重,年长,光头或布满银丝,然后以专业的态度,以饱满的激情去跟你客户宣讲,杀伤力巨大.所以,卖 ...
- oracle增量备份
在进行数据库维护的过程中经常会遇到数据库备份的问题.先介绍一种常用的数据备份操作系统执行计划+批处理命令:在win的系统中存在 任务计划程序 选项:新建任务选中你写好的程序,设定好时间,就可以按照设定 ...