博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4747 Mex
阅读量:6578 次
发布时间:2019-06-24

本文共 2677 字,大约阅读时间需要 8 分钟。

题意:

给出一段数字a  定义mex(l,r)表示a[l]...a[r]中最小的不连续的数字  求出全部mex(l,r)的和

思路:

首先能够想到由l開始到n的全部数字的mex值必定是递增的  那么就能够求出以1開始到n的全部数字的mex  从前到后扫一遍就可以  这时能够求出[1,r]全部区间的mex和  利用线段树就可以

接着考虑怎样求[2,r]、[3,r]....  由[1,r]到[2,r]的转变无非是去掉第一个数字  那么去掉一个数字的影响是什么呢?

比方去掉一个2  那他最多影响到下一个2出现的地方  并且  他仅仅是把mex>2的地方改成了2  即从2处截断  又由于之前所说的递增关系  所以影响的区间也一定是连续的!

那么我们就能够每次删掉一个数字  利用线段树找出他影响的区间  并把这个区间覆盖为那个删掉的数字

最后每次求和就是答案

代码:

#include
#include
#include
#include
using namespace std;typedef __int64 ll;#define N 201000#define L(x) (x<<1)#define R(x) ((x<<1)|1)struct node{ int l,r,val,lazy; ll sum;}tree[N*4];int a[N],mex[N],next[N];int n,l,r;map
mp;ll ans;void up(int i){ tree[i].val=max(tree[L(i)].val,tree[R(i)].val); tree[i].sum=tree[L(i)].sum+tree[R(i)].sum;}void down(int i){ if(tree[i].lazy!=-1) { tree[L(i)].lazy=tree[i].lazy; tree[L(i)].val=tree[i].lazy; tree[L(i)].sum=(tree[L(i)].r-tree[L(i)].l+1)*tree[i].lazy; tree[R(i)].lazy=tree[i].lazy; tree[R(i)].val=tree[i].lazy; tree[R(i)].sum=(tree[R(i)].r-tree[R(i)].l+1)*tree[i].lazy; tree[i].lazy=-1; }}void init(int l,int r,int i){ tree[i].l=l; tree[i].r=r; tree[i].lazy=-1; if(l==r) { tree[i].val=mex[l]; tree[i].sum=mex[l]; return ; } int mid=(l+r)>>1; init(l,mid,L(i)); init(mid+1,r,R(i)); up(i);}void update(int l,int r,int i,int k){ if(l==tree[i].l&&r==tree[i].r) { tree[i].sum=(tree[i].r-tree[i].l+1)*k; tree[i].val=k; tree[i].lazy=k; return ; } down(i); int mid=(tree[i].l+tree[i].r)>>1; if(r<=mid) update(l,r,L(i),k); else if(l>mid) update(l,r,R(i),k); else { update(l,mid,L(i),k); update(mid+1,r,R(i),k); } up(i);}void query(int i,int k){ if(tree[i].l==tree[i].r) { if(tree[i].val>k) l=tree[i].l; else l=n+1; return ; } down(i); if(tree[L(i)].val>k) query(L(i),k); else query(R(i),k); up(i);}int main(){ int i,j; while(~scanf("%d",&n)) { if(!n) break; mp.clear(); // get mex j=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); mp[a[i]]=1; while(mp[j]) j++; mex[i]=j; } mp.clear(); // get next for(i=1;i<=n;i++) mp[a[i]]=n+1; for(i=n;i>=1;i--) { next[i]=mp[a[i]]; mp[a[i]]=i; } //for(i=1;i<=n;i++) printf("%d %d\n",mex[i],next[i]); init(1,n,1); for(i=1,ans=0;i<=n;i++) { ans+=tree[1].sum; query(1,a[i]); r=next[i]; //printf("%d %d\n",l,r); if(l

转载地址:http://eoyno.baihongyu.com/

你可能感兴趣的文章
C# 枚举显示中文
查看>>
React是UI的未来吗?
查看>>
饿了么口碑实现超30亿美元独立融资 阿里软银领投
查看>>
火热的比特币创始人“中本聪”到底是谁?国外网友又有了新猜测!
查看>>
新西兰信报:移民规则变化 赴新中国学生人数减少
查看>>
中国人社部:2018年15个省(区、市)调整最低工资标准
查看>>
2019年春运启动 4683公里新线首次投入春运
查看>>
“小候鸟”返乡过年 无人陪伴儿童出行迎高峰
查看>>
2019年福彩新春贺词
查看>>
阿里云成中国唯一一家进入Forrester大数据服务榜单的科技公司
查看>>
深度预警:深入理解HBase的系统架构
查看>>
从 Java 到 Scala(一):面向对象谈起
查看>>
JSP第六篇【自定义标签之传统标签】
查看>>
Weex 事件传递的那些事儿
查看>>
Android性能优化:关于 内存泄露 的知识都在这里了!
查看>>
【备战春招/秋招系列】美团面经总结基础篇 (附详解答案)
查看>>
Rokid(全栈语音智能开发套件)开箱记
查看>>
Leetcode 215 First K Largest Element
查看>>
百度啊,你是新年第一惨
查看>>
TensorFlow发布重要更新AutoGraph
查看>>