Mex
Time Limit: 5000ms
Memory Limit: 65535KB
This problem will be judged on HDU. Original ID: 474764-bit integer IO format: %I64d Java class name: Main
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.
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.
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.
Sample Input
3 0 1 3 5 1 0 2 0 1 0
Sample Output
5 24
Hint
For the first test case: mex(1,1)=1, mex(1,2)=2, mex(1,3)=2, mex(2,2)=0, mex(2,3)=0,mex(3,3)=0. 1 + 2 + 2 + 0 +0 +0 = 5.
Source
解题:这题好难啊。。。参考自Oyking
那么从0开始考虑,如果只有一个0,出现在了x位置,那么s[1,x-1]的子段的mex值都为0,所以$S[i] = n-x+1(i < x)$,大于 x 的 s[i]都为0(大于x的子段不存在0,他们的最小非负数都为0)
View Code
如果有两个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 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 200010; 5 struct arc { 6 int pos,next; 7 arc(int x = 0,int y = -1) { 8 pos = x; 9 next = y; 10 } 11 } e[maxn<<2]; 12 struct node { 13 LL sum; 14 int lazy,minv,maxv; 15 } tree[maxn<<2]; 16 int head[maxn],a[maxn],tot,n; 17 void add(int u,int pos) { 18 e[tot] = arc(pos,head[u]); 19 head[u] = tot++; 20 } 21 inline void pushup(int v) { 22 tree[v].minv = min(tree[v<<1].minv,tree[v<<1|1].minv); 23 tree[v].maxv = max(tree[v<<1].maxv,tree[v<<1|1].maxv); 24 tree[v].sum = tree[v<<1].sum + tree[v<<1|1].sum; 25 } 26 inline void pushdown(int L,int R,int v) { 27 if(tree[v].lazy != -1) { 28 int mid = (L + R)>>1; 29 tree[v<<1].maxv = tree[v<<1].minv = tree[v].lazy; 30 tree[v<<1].sum = (LL)tree[v].lazy*(mid - L + 1); 31 tree[v<<1].lazy = tree[v].lazy; 32 tree[v<<1|1].maxv = tree[v<<1|1].minv = tree[v].lazy; 33 tree[v<<1|1].lazy = tree[v].lazy; 34 tree[v<<1|1].sum = (LL)tree[v].lazy*(R - mid); 35 tree[v].lazy = -1; 36 } 37 } 38 void build(int lt,int rt,int v) { 39 tree[v].lazy = -1; 40 if(lt == rt) { 41 tree[v].maxv = tree[v].minv = tree[v].sum = n - lt + 1; 42 return; 43 } 44 int mid = (lt + rt)>>1; 45 build(lt,mid,v<<1); 46 build(mid+1,rt,v<<1|1); 47 pushup(v); 48 } 49 void update(int L,int R,int lt,int rt,int val,int v) { 50 if(tree[v].maxv <= val) return; 51 if(lt <= L && rt >= R && tree[v].minv >= val) { 52 tree[v].maxv = tree[v].minv = val; 53 tree[v].sum = LL(val)*(R - L + 1); 54 tree[v].lazy = val; 55 return; 56 } 57 pushdown(L,R,v); 58 int mid = (L + R)>>1; 59 if(lt <= mid) update(L,mid,lt,rt,val,v<<1); 60 if(rt > mid) update(mid+1,R,lt,rt,val,v<<1|1); 61 pushup(v); 62 } 63 int main() { 64 while(scanf("%d",&n),n) { 65 memset(head,-1,sizeof head); 66 tot = 0; 67 for(int i = 1; i <= n; ++i) scanf("%d",a+i); 68 for(int i = n; i > 0; --i) if(a[i] <= n) add(a[i],i); 69 build(1,n,1); 70 LL ret = 0; 71 for(int i = 0; i <= n && tree[1].sum; ++i){ 72 int last = 0; 73 for(int j = head[i]; ~j; j = e[j].next){ 74 update(1,n,last+1,e[j].pos, n - e[j].pos + 1,1); 75 last = e[j].pos; 76 } 77 if(last < n) update(1,n,last + 1,n,0,1); 78 ret += tree[1].sum; 79 } 80 printf("%I64d ",ret); 81 } 82 return 0; 83 }