HDU 4747 Mex「建议收藏」

HDU 4747 Mex

大家好,又见面了,我是全栈君。

题意:

给出一段数字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<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
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<int,int> 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<r)
            {
                update(l,r-1,1,a[i]);
            }
            update(i,i,1,0);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116215.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • H5标签datalist

    H5标签datalist实现输入框的搜索联想功能简介datalist标签的说明和用法说明用法效果简介有的时候前端为了更好地实现输入框input的交互效果,需要增加搜索联想功能,除了使用已经封装好的组件或者自己手写js以外,我们可以使用datalist标签更简便地去实现这个功能。datalist标签的说明和用法说明datalist标签用来定义选项列表,需要与input元素配合使用,来定义input可能的值…

    2025年6月19日
    0
  • 精读论文题目_in large part as a consequence

    精读论文题目_in large part as a consequence基于高鲁棒性的弹性扭曲视差容忍图像拼接算法

    2022年9月15日
    1
  • 什么是SOA架构?为什么使用SOA架构?「建议收藏」

    什么是SOA架构?为什么使用SOA架构?「建议收藏」SOA架构简介面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以以一种统一和通用的方式进行交互**SOA具有以下五个特征**1.可重用;2.松耦合;3.明确定义的接口;…

    2022年6月24日
    27
  • c语言逻辑运算符!_c语言中关系运算符

    c语言逻辑运算符!_c语言中关系运算符&|~^>><<&&||!运算符包括逻辑运算符与位运算符。逻辑运算符针对的就是真假问题,或者说01问题,也就是bool类型的。位运算符重点在于位操作,也就是对每一位进行操作。下面逐个介绍。&当&两边是bool类型的值时,该运算符作为逻辑运算符。作用如下:当运算符两边的表达式的…

    2022年9月1日
    0
  • 六款大数据采集平台的架构分析

    六款大数据采集平台的架构分析本文转自:《六款大数据采集平台的架构分析》文中介绍了目前业界存在的六款数据采集平台,数据采集平台可以作为数据平台的日志采集系统,个人尝试过Flume+ES+Kibana这样的开源组合,为什么这么选,因为Flume非常灵活且无缝的支持Hadoop生态系统的大部分组件,ES和Kibana也是比较成熟的开源大数据实时搜索展示的组合。随着大数据越

    2022年6月10日
    30
  • bloom过滤器原理_gabor filter

    bloom过滤器原理_gabor filterBloomFilter概念和原理焦萌2007年1月27日 BloomFilter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。BloomFilter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(falsepositive)。因此,BloomFilter不适

    2022年10月23日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号