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):
 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL; #define ll x * 2
#define rr x * 2 + 1 const int MAXN = ; LL tree[MAXN * ];
int maxt[MAXN * ], mint[MAXN * ];
int a[MAXN], n; int head[MAXN], lcnt;
int pos[MAXN], next[MAXN]; void init() {
memset(head, , (n + ) * sizeof(int));
lcnt = ;
} void add_link(int x, int i) {
pos[lcnt] = i; next[lcnt] = head[x]; head[x] = lcnt++;
} void build(int x, int left, int right) {
if(left == right) tree[x] = maxt[x] = mint[x] = n - left + ;
else {
int mid = (left + right) >> ;
if(left <= mid) build(ll, left, mid);
if(mid < right) build(rr, mid + , right);
tree[x] = tree[ll] + tree[rr];
maxt[x] = max(maxt[ll], maxt[rr]);
mint[x] = min(mint[ll], mint[rr]);
}
} void update(int x, int left, int right, int a, int b, int val) {
if(a <= left && right <= b && mint[x] >= val) {
tree[x] = LL(val) * (right - left + );
maxt[x] = mint[x] = val;
}
else {
if(right == left) return ;
int mid = (left + right) >> ;
if(maxt[x] == mint[x]) {
maxt[ll] = mint[ll] = maxt[x];
tree[ll] = LL(mid - left + ) * maxt[x];
maxt[rr] = mint[rr] = maxt[x];
tree[rr] = LL(right - (mid + ) + ) * maxt[x];
}
if(a <= mid && maxt[ll] > val) update(ll, left, mid, a, b, val);
if(mid < b && maxt[rr] > val) update(rr, mid + , right, a, b, val);
tree[x] = tree[ll] + tree[rr];
maxt[x] = max(maxt[ll], maxt[rr]);
mint[x] = min(mint[ll], mint[rr]);
}
} LL solve() {
LL ret = ;
build(, , n);
for(int i = ; i <= n && tree[]; ++i) {
int last = ;
for(int p = head[i]; p; p = next[p]) {
update(, , n, last + , pos[p], n - pos[p] + );
last = pos[p];
}
update(, , n, last + , n, );
ret += tree[];
}
return ret;
} int main() {
while(scanf("%d", &n) != EOF && n) {
for(int i = ; i <= n; ++i) scanf("%d", &a[i]);
init();
for(int i = n; i > ; --i) if(a[i] <= n) add_link(a[i], i);
cout<<solve()<<endl;
}
}

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. 表达式过滤器 uppercase

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  2. 有连接服务&无连接服务

    面向连接的服务 通信双方在通信时要事先建立一条通信线路,其过程包括建立连接.使用链接.释放链接三个过程 如: TCP 电话 面向无连接的服务 通信双方不需要事先建立一条通信线路,而是把每个带有目的选址 ...

  3. Long数组转String数组

    public static String[] longToString(Long longArray[]) { if (longArray == null || longArray.length &l ...

  4. BigDecimal运算(加、减、乘、除)

    public class BigDecimalOperation { private BigDecimalOperation(){ } public static BigDecimal add(dou ...

  5. vuex vue状态管理

    第一步安装vuex(安装在生产环境) npm install vuex 第二步 src下新建store文件夹 用来专门放状态管理,store文件夹下新建四个js文件 index.js  actions ...

  6. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  7. 三种for循环遍历

    import java.util.ArrayList;import java.util.Iterator;import java.util.List; public class  For{ publi ...

  8. 路由器基础配置之广播多路访问链路上的ospf

    我们将以上面的拓扑图进行实验,因为是要以不断广播的形式进行ospf,所有中间加了一个集线器,这种ospf和前一种不同,路由器之间会在配置好ospf之后选举出一个老大,DR,一个备份,BDR,而其他路由 ...

  9. PHPPCRE正则解析

    一.前言 前面的博客里,有对字符集的解析.这里就不是字符集的事儿了,在PHP中很多函数的处理默认是unicode中的UTF-8编码格式.那么废话不多说,直接开始正题. 二.PHP函数mb_split解 ...

  10. Python学习:变量

    变量(Variables): 是为了存储程序在运算过程中的一些中间结果,为了方便日后调用储存在计算的内存中 官方介绍: Variables are used to storeinformation t ...