1、题目大意:对一个序列的每一个区间求Mex,最后所有的mex相加(mex就是SG的那个),力求nlogn。。。

2、分析:最近开始刷线段树了,还是有很多不会啊

首先把1-1 1-2 1-… 1-n这些区间的mex算出来,他一定是单调递增的,那么以2为左端点的区间,

他们的mex是可以用线段树做区间修改以1为左端点的区间的,比若说我们要修改以2为左端点的,

这个序列,下一次出现a[1]这个数的地方以后都没有影响,这是一定的

然后我们对于2到a[1]这些值所代表的区间mex值,我们就是要算qo = min(q[o], a[1]);

以为q[o]是单调的,所以我们可以二分,但是以为这道题是lazy所以二分的复杂度是log^2n,(因为要单点询问)

然而这会TLE

后来看了网上的kuangbin的blog里有这个的处理方法, 再维护一个区间最小值,然后写一个神奇的函数

这是一个递归函数,如果左儿子区间的RMQ

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
struct segment_tree{
    LL q[2000000];
    LL m[2000000];
    LL lazy[2000000];
    LL x, y, z;
    void add(LL l, LL r, LL o){
        if(lazy[o] != -1){
            lazy[2 * o] = lazy[o];
            lazy[2 * o + 1] = lazy[o];
            q[o] = (LL)lazy[o] * (r - l + 1);
            m[o] = lazy[o];
            lazy[o] = -1;
        }
        if(x > r || y < l) return;
        if(x <= l && r <= y){
            lazy[2 * o] = z;
            lazy[2 * o + 1] = z;
            q[o] = z * (r - l + 1);
            m[o] = z;
            return;
        }
        LL mid = (l + r) / 2;
        add(l, mid, 2 * o);
        add(mid + 1, r, 2 * o + 1);
        q[o] = q[2 * o] + q[2 * o + 1];
        m[o] = m[2 * o];
        if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
        return;
    }
    LL query(LL l, LL r, LL o){
        if(lazy[o] != -1){
            lazy[2 * o] = lazy[o];
            lazy[2 * o + 1] = lazy[o];
            q[o] = (LL)lazy[o] * (r - l + 1);
            m[o] = lazy[o];
            lazy[o] = -1;
        }
        if(x > r || y < l) return 0;
        if(x <= l && r <= y) return q[o];
        LL mid = (l + r) / 2;
        LL ret = 0;
        ret += query(l, mid, 2 * o);
        ret += query(mid + 1, r, 2 * o + 1);
        q[o] = q[2 * o] + q[2 * o + 1];
        m[o] = m[2 * o];
        if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
        return ret;
    }
    LL get(LL l, LL r, LL o, LL u, LL st){
        if(lazy[o] != -1){
            lazy[2 * o] = lazy[o];
            lazy[2 * o + 1] = lazy[o];
            q[o] = (LL)lazy[o] * (r - l + 1);
            m[o] = lazy[o];
            lazy[o] = -1;
        }
        if(m[o] < u) return 0;
        if(st == 1) return 0;
        if(l == r) return l;
        LL mid = (l + r) / 2;
        LL ret = 1;
        LL wl;
        if(mid < x){
            ret = 0;
            wl = get(l, mid, 2 * o, u, 1);
        }
        else ret = get(l, mid, 2 * o, u, 0);
        if(ret == 0) ret = get(mid + 1, r, 2 * o + 1, u, 0);
        else wl = get(mid + 1, r, 2 * o + 1, u, 1);
        q[o] = q[2 * o] + q[2 * o + 1];
        m[o] = m[2 * o];
        if(m[2 * o + 1] > m[o]) m[o] = m[2 * o + 1];
        return ret;
    }
} wt;
LL value[1000000];
bool vis[1000000];
LL head[1000000];
LL Next[1000000];
int main(){
    LL n;
    while(scanf("%I64d", &n) != EOF){
        if(n == 0) return 0;
        LL ans = 0;
        wt.x = 1;
        wt.y = n;
        wt.z = 0;
        wt.add(1, n, 1);
        memset(vis, 0, sizeof(vis));
        for(LL i = 0; i <= 300000; i ++) head[i] = n + 1;
        for(LL i = 1; i <= n; i ++) scanf("%I64d", &value[i]);
        LL o = 0;
        for(LL i = 1; i <= n; i ++){
            if(value[i] < n) vis[value[i]] = 1;
            while(vis[o]) o ++;
            wt.x = i; wt.y = i; wt.z = o;
            wt.add(1, n, 1);
            ans += o;
        }
        for(LL i = n; i >= 1; i --){
            if(value[i] < n){
                Next[i] = head[value[i]];
                head[value[i]] = i;
            }
        }
        for(LL i = 2; i <= n; i ++){
            LL h = value[i - 1];
            wt.x = i;
            LL l = wt.get(1, n, 1, h, 0);
            if(l <= Next[i - 1] - 1 && l != 0){
                wt.x = l; wt.y = Next[i - 1] - 1; wt.z = h;
                wt.add(1, n, 1);
            }
            wt.x = i; wt.y = n;
            ans += wt.query(1, n, 1);
        }
        printf("%I64d\n", ans);
    }
     return 0;
} 

hdu4747——Mex的更多相关文章

  1. HDU-4747 Mex(线段树区间更新)

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

  2. HDU-4747 Mex 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:求一个数列中,所有mex(L,R)的和. 注意到mex是单调不降的,那么首先预处理出mex ...

  3. [置顶] hdu4747 Mex 线段树

    题意:给你一个序列,让你求出对于所有区间<i, j>的mex和,mex表示该区间没有出现过的最小的整数. 思路:从时限和点数就可以看出是线段树,并且我们可以枚举左端点i, 然后求出所有左端 ...

  4. [hdu4747]Mex

    首先计算出以1为左端点的所有区间的mex,考虑删除左端点仍然维护这个序列:设当前删除点下一次出现在y,y~n的mex不变,从左端点到y的点中大于删除值的点要变成删除值,因为这个是不断递增的,所以是一段 ...

  5. HDU4747:Mex(线段树区间修改)

    传送门 题意: 给出\(n\)个数,然后求\(\sum_{i=1}^n\sum_{j=i}^nmex(i,j)\).\(mex(i,j)\)表示区间\([i,j]\)的\(mex\). 思路: 考虑枚 ...

  6. Codeforces Round #381 (Div. 2)C. Alyona and mex(思维)

    C. Alyona and mex Problem Description: Alyona's mother wants to present an array of n non-negative i ...

  7. Codeforces 740C. Alyona and mex 思路模拟

    C. Alyona and mex time limit per test: 2 seconds memory limit per test: 256 megabytes input: standar ...

  8. bzoj3339 rmq problem (range mex query)

    给一个长度为n的数列a,q个询问,每次询问一段区间的mex.(没有出现过的最小非负整数) 1<=n,q<=200000,0<=ai<=200000. 题解1 莫队 我们将权值分 ...

  9. 转:在VS2010下编译、调试和生成mex文件

    最近帮人调了一个程序,是网上公开的代码,利用matlab与c++混合编程做三维模型关键点检测,发现他们可以用VS2010编译.调试.生成mexw32文件,因此觉得之前在Matlab上利用mex命令真是 ...

随机推荐

  1. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  2. My latest news (--2016.10)

    2016.10.31 22:44 一个“程序”,打代码占40%.思考占60% 2016.10.30 20:53 周末,话说今天有晚上讲座,还点名,了,悲催.之前学习的Qt有点问题,悲催.推荐个博文:h ...

  3. 图片延迟加载jquery插件imgLazyLoad(三)

    此Jquery插件是在图片加载前显示一个加载图片,当图片下载完毕后显示图片出来,可对图片进行是否自动缩放功能,此Jquery插件使用时可让页面先加载,而图片后加载的方式,解决了平时使用时要在图片显示出 ...

  4. 网页js,DIV全屏布局

    <script type="text/javascript"> $(document).ready(function(){ findDimensions(); }); ...

  5. Quartz.NET总结(一)入门

    前段时间,花了大量的时间,将原先的计划任务,切换到Quartz.NET来进行管理.原先的后台定时服务都是通过计划任务来实现的,但是随着业务增长,计划任务也越来越多,每个后台服务,都得创建一个计划任务. ...

  6. JAVA数组的典型操作

  7. CSS3新增基础属性总结——20160409(易达客)

    1.box-shadow :h-shadow v-shadow blur spread color inset(outset) h-shadow:必须:水平阴影位置,允许负值. v-shadow:必须 ...

  8. MSSQL数据库索引的应用

    一.索引的概念 索引就是加快检索表中数据的方法.数据库的索引类似于书籍的索引.在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息.在数据库中,索引也允许数据库程序迅速地找到表中的数据,而 ...

  9. MYSql存储过程的作用及语法

    1.使用了存过程,很多相似性的删除,更新,新增等操作就变得轻松了,并且以后也便于管理! 2.存储过程因为SQL语句已经预编绎过了,因此运行的速度比较快. 3.存储过程可以接受参数.输出参数.返回单个或 ...

  10. 【转】Kafka实战-Flume到Kafka

    Kafka实战-Flume到Kafka Kafka   2015-07-03 08:46:24 发布 您的评价:       0.0   收藏     2收藏 1.概述 前面给大家介绍了整个Kafka ...