Problem Description
Mex is a function on a set of integers, which is universally used for impartial game theorem. For a non-negative integer set S, mex(S) is defined as the least non-negative integer which is not appeared in S. Now our problem is about mex function on a sequence.

Consider a sequence of non-negative integers {ai}, we define mex(L,R) as the least non-negative integer which is not appeared in the continuous subsequence from aL to aR, inclusive. Now we want to calculate the sum of mex(L,R) for all 1 <= L <= R <= n.

 
Input
The input contains at most 20 test cases.
For each test case, the first line contains one integer n, denoting the length of sequence.
The next line contains n non-integers separated by space, denoting the sequence.
(1 <= n <= 200000, 0 <= ai <= 10^9)
The input ends with n = 0.
 
Output
For each test case, output one line containing a integer denoting the answer.
 
题目大意:定义mex(l,r)为S[l, r]中没出现的最小的非负数。求$ \sum mex(i,j) $,0≤i≤j≤n
思路:我总觉得自己思路有点奇葩大家将就着看。。
考虑每一个子段S[l,n],如果S[l,n]的第一个0出现在 i ( i 在 l 和 n 之间),那么S[l, i-1]的mex值都为0。
按这个思路搞,考虑S[i]为从以S[i](1≤i≤n)开头还没确定mex值的子段数,那么初始化为S[i] = n-i+1(数组从1开始计数)
/* 补充说明一下s[i]
  就是什么都没做的时候,比如s[1] = n
  然后只有一个0在位置3
  那么就可以确定mex[1,1]和mex[1,2]为0了,mex[1,i],i≥3都至少为1,但还不知道他们会不会大于1,所以s[1] = n - 2
  然后只有一个1在位置7
  那么就可以确定mex[1,i],3≤i<7,都为1(都只有0没有1),而i≥7的mex[1,i]都至少为2(他们都含有0和1),所以s[1] = n - 7
  s[i]就是从i开始的mex[i,x]在第 p 阶段还没有确定值只知道有s[i]个mex[i,x]至少大于p
*/
那么从0开始考虑,如果只有一个0,出现在了x位置,那么s[1,x-1]的子段的mex值都为0,所以S[i] = n-x+1(i < x),大于 x 的 s[i]都为0(大于x的子段不存在0,他们的最小非负数都为0)
如果有两个0,那么设第一个0位置为x,第二个0位置为y,那么s[i] = n-x+1(i < x),s[i] = n - y + 1(x≤i<y),大于 y 的 s[i]都为0
有多个0也一样,处理完0之后,得到的sum{s[i]}就是最少为1的mex子段数
然后从1开始往上处理,对某一个数在位置x,s[i] = min(n-x+1, s[i])。
每处理完一个数,就得到一个$ \sum s[i] $ ,依次可以得到最少为2的mex字段数,最少为3的mex字段数……把这些都加起来就是答案。
 
说得有点抽象……举个例子1 0 2 0 1
初始化s[1] = 5, s[2] = 4, s[3] = 3, s[4] = 2, s[5] = 1
那么处理数字0,s[1] = 4, s[2] = 4, s[3] = 2, s[4] = 2, s[5] = 0, ans = 12
处理数字1,s[1] = 4, s[2] = 1, s[3] = 1, s[4] = 1, s[5] = 0, ans = 12 + 7 = 19
处理数字2,s[1] = 3, s[2] = 1, s[3] = 1, s[4] = 0, s[5] = 0, ans = 19 + 5 = 24
 
那么可以看出这个是区间赋值,采用线段树处理可以在O(nlogn)的时间内解出答案。
 
代码(1000MS):
  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long LL;
  7.  
  8. #define ll x * 2
  9. #define rr x * 2 + 1
  10.  
  11. const int MAXN = ;
  12.  
  13. LL tree[MAXN * ];
  14. int maxt[MAXN * ], mint[MAXN * ];
  15. int a[MAXN], n;
  16.  
  17. int head[MAXN], lcnt;
  18. int pos[MAXN], next[MAXN];
  19.  
  20. void init() {
  21. memset(head, , (n + ) * sizeof(int));
  22. lcnt = ;
  23. }
  24.  
  25. void add_link(int x, int i) {
  26. pos[lcnt] = i; next[lcnt] = head[x]; head[x] = lcnt++;
  27. }
  28.  
  29. void build(int x, int left, int right) {
  30. if(left == right) tree[x] = maxt[x] = mint[x] = n - left + ;
  31. else {
  32. int mid = (left + right) >> ;
  33. if(left <= mid) build(ll, left, mid);
  34. if(mid < right) build(rr, mid + , right);
  35. tree[x] = tree[ll] + tree[rr];
  36. maxt[x] = max(maxt[ll], maxt[rr]);
  37. mint[x] = min(mint[ll], mint[rr]);
  38. }
  39. }
  40.  
  41. void update(int x, int left, int right, int a, int b, int val) {
  42. if(a <= left && right <= b && mint[x] >= val) {
  43. tree[x] = LL(val) * (right - left + );
  44. maxt[x] = mint[x] = val;
  45. }
  46. else {
  47. if(right == left) return ;
  48. int mid = (left + right) >> ;
  49. if(maxt[x] == mint[x]) {
  50. maxt[ll] = mint[ll] = maxt[x];
  51. tree[ll] = LL(mid - left + ) * maxt[x];
  52. maxt[rr] = mint[rr] = maxt[x];
  53. tree[rr] = LL(right - (mid + ) + ) * maxt[x];
  54. }
  55. if(a <= mid && maxt[ll] > val) update(ll, left, mid, a, b, val);
  56. if(mid < b && maxt[rr] > val) update(rr, mid + , right, a, b, val);
  57. tree[x] = tree[ll] + tree[rr];
  58. maxt[x] = max(maxt[ll], maxt[rr]);
  59. mint[x] = min(mint[ll], mint[rr]);
  60. }
  61. }
  62.  
  63. LL solve() {
  64. LL ret = ;
  65. build(, , n);
  66. for(int i = ; i <= n && tree[]; ++i) {
  67. int last = ;
  68. for(int p = head[i]; p; p = next[p]) {
  69. update(, , n, last + , pos[p], n - pos[p] + );
  70. last = pos[p];
  71. }
  72. update(, , n, last + , n, );
  73. ret += tree[];
  74. }
  75. return ret;
  76. }
  77.  
  78. int main() {
  79. while(scanf("%d", &n) != EOF && n) {
  80. for(int i = ; i <= n; ++i) scanf("%d", &a[i]);
  81. init();
  82. for(int i = n; i > ; --i) if(a[i] <= n) add_link(a[i], i);
  83. cout<<solve()<<endl;
  84. }
  85. }

HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)的更多相关文章

  1. hdu 4747 Mex (2013 ACM/ICPC Asia Regional Hangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 思路: 比赛打得太菜了,不想写....线段树莽一下 实现代码: #include<iost ...

  2. HDU4747——2013 ACM/ICPC Asia Regional Hangzhou Online

    啦啦啦. 这是杭州网赛的一个题目,当时没做出来,当然这个想法确实比较难想到. 题目质量很高,这个题目也很特别,以前都没做过类似的题目.让我又一次体验了线段树的强大力量. 题目的意思是给你n个数a1-a ...

  3. [2013 ACM/ICPC Asia Regional Hangzhou Online J/1010]hdu 4747 Mex (线段树)

    题意: + ;];;;], seg[rt <<  | ]);)) * fa.setv;) * fa.setv;;], seg[rt <<  | ], r - l + );;,  ...

  4. HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online

    与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了. 这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊. 题目的意思是给你两个串,每个串只含有R或者D,要 ...

  5. hdu 4751 Divide Groups bfs (2013 ACM/ICPC Asia Regional Nanjing Online 1004)

    SDUST的训练赛 当时死磕这个水题3个小时,也无心去搞其他的 按照题意,转换成无向图,预处理去掉单向的边,然后判断剩下的图能否构成两个无向完全图(ps一个完全图也行或是一个完全图+一个孤点) 代码是 ...

  6. HDU 4745 Two Rabbits(最长回文子序列)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Description Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon ...

  7. HDU 4744 Starloop System(最小费用最大流)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Description At the end of the 200013 th year of the Galaxy era, the war between Carbon-based lives a ...

  8. 2013 ACM/ICPC Asia Regional Hangzhou Online hdu4739 Zhuge Liang's Mines

    Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. HDU4745——Two Rabbits——2013 ACM/ICPC Asia Regional Hangzhou Online

    这个题目虽然在比赛的时候苦思无果,但是赛后再做就真的是个水题,赤果果的水题. 题目的意思是给n个数构成的环,两只兔子从任一点开始分别顺逆时针跳,每次可以调到任意一个数(最多不会跳过一圈). 求最多能跳 ...

随机推荐

  1. JavaScript创建对象的三种方法

    在 JavaScript 中我们知道无法通过类来创建对象,那么如何创建对象呢? (1)通过“字面量”方式创建对象 将你的信息写到{ }中,并赋值给一个变量,此时这个变量就是一个对象,例: var ga ...

  2. Oracle db file parallel write 和 log file parallel write 等待事件

    一. db file parallel write等待事件 引自如下blog: http://oradbpedia.com/wiki/Wait_Events_-_db_file_parallel_wr ...

  3. iOS-GCD使用详解

    前言 对初学者来说,GCD似乎是一道迈不过去的坎,很多人在同步.异步.串行.并行和死锁这几个名词的漩涡中渐渐放弃治疗.本文将使用图文表并茂的方式给大家形象地解释其中的原理和规律. 线程.任务和队列的概 ...

  4. 技巧:Vimdiff 使用

    技巧:Vimdiff 使用 各种 IDE 大行其道的同时,传统的命令行工具以其短小精悍,随手可得的特点仍有很大的生存空间,这篇短文介绍了一个文本比较和合并的小工具:vimdiff.希望能对在 Unix ...

  5. Debug实验学习汇编

    R命令查看.改变CPU寄存器的内容: D命令查看内存中的内容: E命令改写内存中的内容: U命令将内存中的机器指令翻译成汇编指令: T命令执行一条机器指令: A命令以汇编指令的格式在内存中写入一条机器 ...

  6. MySQL-5.7.20主从复制测试[20180110]

    前言     MySQL 5.7.20测试主从复制   环境     主库 192.168.1.59  t-xi-sonar01     从库 192.168.1.51  t-xi-orc01   设 ...

  7. Percona-Tookit工具包之pt-index-usage

      Preface       There're many ways relevent with performance tuning.For example,using indexes proper ...

  8. Linux入门-第六周

    1.总结IP地址规划 IP地址的合理规划是网络设计中最重要的一环,在大型网络中必须对IP地址进行统一规划并得到实施.IP地址规划的好坏影响到网络路由协议算法的效率,影响到网络的性能,影响到网络的拓展, ...

  9. Layabox进阶之资源加载

    资源加载失败,图片资源默认类型是image 如果是sprite可能找不到. 资源的加载顺序,场景被加载出来时,要判断该场景的资源是否都已经加载到. 点击A界面弹出来B界面,A界面的资源要在B界面之前加 ...

  10. python函数的返回值

    返回值:return1.没有返回值    #不写return    #只写return:结束一个函数    #return None2.有一个返回值    #可以返回任何数据类型    #只要返回就可 ...