4747

思路:

线段树

先求出mex(1,1), mex(1, 2) , mex(1,3),...,mex(1,n)(单调上升),先将这些mex放进线段树里求和

然后再求出next[i]表示下一次出现a[i] 的位置

然后从前往后不停的删数,对于一个数a[i],我们删掉他的影响是:l为mex大于a[i]的位置,r 为next[i],l 到 r-1 之间的 mex都变为 a[i]

然后这个线段树只需要维护区间最大值(方便查找第一个大于a[i]的位置)和区间和就可以了

代码:

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//headconst int N = 2e5 + 5;
int a[N], nxt[N], mx[N<<2], lazy[N<<2], mex[N];
LL sum[N<<2];
map<int, int>mp;
void push_up(int rt) {sum[rt] = sum[rt<<1] + sum[rt<<1|1];mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
}
void push_down(int rt, int len) {sum[rt<<1] = 1LL * lazy[rt] * (len - (len >> 1));mx[rt<<1] = lazy[rt];lazy[rt<<1] = lazy[rt];sum[rt<<1|1] = 1LL * lazy[rt] * (len >> 1);mx[rt<<1|1] = lazy[rt];lazy[rt<<1|1] = lazy[rt];lazy[rt] = 0;
}
void build(int rt, int l, int r) {if(l == r) {mx[rt] = sum[rt] = mex[l];return ;}int m = (l+r) >> 1;build(ls);build(rs);push_up(rt);
}
void update(int x, int L, int R, int rt, int l, int r) {if(L <= l && r <= R) {mx[rt] = x;sum[rt] = 1LL * (r-l+1) * x;lazy[rt] = x;return ;}if(lazy[rt]) push_down(rt, r-l+1);int m = (l+r) >> 1;if(L <= m) update(x, L, R, ls);if(R > m) update(x, L, R, rs);push_up(rt);
}
LL query(int L, int R, int rt, int l, int r) {if(L <= l && r <= R) return sum[rt];if(lazy[rt]) push_down(rt, r-l+1);int m = (l+r) >> 1;LL ans = 0;if(L <= m) ans += query(L, R, ls);if(R > m) ans += query(L, R, rs);push_up(rt);return ans;
}
int Find(int x, int rt, int l, int r) {if(l == r) return l;int m = (l+r) >> 1;if(lazy[rt]) push_down(rt, r-l+1);if(mx[rt<<1] > x) return Find(x, ls);else return Find(x, rs);
}
int main() {int n;while(~scanf("%d", &n) && n) {mem(lazy, 0);build(1, 1, n);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);mp.clear();int tmp = 0;for (int i = 1; i <= n; i++) {mp[a[i]]++;while(mp.find(tmp) != mp.end()) tmp++;mex[i] = tmp;}build(1, 1, n);mp.clear();for (int i = n; i >= 1; i--) {if(mp.find(a[i]) == mp.end()) nxt[i] = n+1;else nxt[i] = mp[a[i]];mp[a[i]] = i;}LL ans = 0;for (int i = 1; i <= n; i++) {ans += query(1, n, 1, 1, n);if(mx[1] <= a[i]) continue;int l = Find(a[i], 1, 1, n);int r = nxt[i];if(l < r) update(a[i], l, r-1, 1, 1, n);}printf("%lld\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/widsom/p/9118494.html

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【线段树上二分+扫描线】

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

  3. HDU - 4747 Mex(线段树)

    题意: 计算    其中mex即为博弈中出现的mex(未出现的最小非负整数). 分析: 有两种方法,递推有点懵(以后再来补QAQ),就写了线段树 想法是每次求以i为起点的区间的mex值的和,最后累加即 ...

  4. HDOJ 4747 Mex

    非常好的线段树题....此题必定会火..... Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K ( ...

  5. 动态规划总结与题目分类

    源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...

  6. 『ACM-算法-动态规划』初识DP动态规划算法

    一.多阶段决策过程的最优化问题 在现实生活中,有类活 动的过程,由于 它的特殊性,可将过程分成若干个互相阶段.在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.当阶段决策的选取不是任意确 ...

  7. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

  8. 《动态规划》— 动态规划分类

    动态规划(英语:Dynamic programming,DP)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最 ...

  9. 转:动态规划题目分类

    https://blog.csdn.net/cc_again/article/details/25866971 一.简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见 ...

最新文章

  1. 浅谈 JavaScriptCore
  2. 长江存储年底提供自研32层堆叠3D NAND闪存样品
  3. (专题二)01 矩阵的处理-特殊矩阵
  4. python methodtype_Python的实例定属性和方法或类绑定方法
  5. 如何做一个有品位的程序员
  6. OpenCV :(-5:Bad argument) Matrix operand is an empty matrix. in function ‘checkOperandsExist‘
  7. 姐们儿,你就忍了吧—咱们一起骂老板(4)
  8. python股票收益率计算_股票分析之——收益率(附完整代码和讲解)
  9. 使用Python、pandas、pyecharts进行数据分析——实例讲解
  10. java word书签_java和javascript获取word的 书签位置
  11. 朴素贝叶斯——新闻分类
  12. 车牌规格以及识别中的不利因素
  13. ERP系统具有哪些功能?
  14. 金庸武侠内功排行榜TOP10
  15. mysql取第一行数据_select取第一行数据
  16. 新番 | 万万没想到,Hulu有一天也开始推新番了
  17. 整型转换为32位二进制字符串
  18. 6只做化验用的玻璃杯,前面3只盛满了水,后面3只是空的。你能只移动1只玻璃杯,就便盛满水的杯子和空杯子间隔起来吗?
  19. 零一背包问题(一维列表逆序的解释)
  20. c语言成绩筛选,c语言筛选质数

热门文章

  1. linux环境下安装nginx步骤(不错)
  2. js获取单选按钮的值
  3. SQL2008R2的 遍历所有表更新统计信息 和 索引重建
  4. Python基础-包
  5. (转)AS3中的stage,this,root的区别
  6. GMF学习系列(二) 一些知识点(续2)
  7. 全国计算机等级考试题库二级C操作题100套(第45套)
  8. MySQL的IFNULL() 函数使用
  9. Java 自动装箱与拆箱
  10. mac下安装brew下载非常慢解决方法