http://acm.hdu.edu.cn/showproblem.php?pid=4747
Problem Descriptionmex is a function on a set of integers, which are universally used for impartial game theorem. For a non-negative integer set S, MEX (S) are defined as the least non-negative integer which is isn't appeared in S. Now we problem is about the 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 APPEA Red 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.
Inputthe input contains at the most 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.
Outputfor each test case, output one line containing a integer denoting the answer.
Sample Input
30 1 351 0 2 0 10
Sample Output
524 Hint for The first Test Case:mex (=1), MEX (=2), MEX (1,3) =2, MEX (2,2) =0, MEX (2,3) =0,mex (3,3) =0. 1 + 2 + 2 + 0 +0 +0 = 5.
/**hdu 4747 Line Tree This problem I have been engaged for two days, looking at the code of the Great God finally a, is not in the mood to write a summary of http://www.cnblogs.com/kuangbin/p/3327674.html*/#include < stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <map>using Namespace Std;typedef long Long ll;const int maxn= 200005;int n;int a[maxn];int mex[maxn];///represents the MEX value of the interval [1,i] int NEXT[MAXN] ;///indicates where the next A[i] value appears map<int,int>mp;struct note{int l,r,mx,lazy; LL sum;} Tree[maxn*4];void update_same (int i,int v) {tree[i].sum= (LL) v* (tree[i].r-tree[i].l+1); Tree[i].mx=v; Tree[i].lazy=1;} void push_up (int i) {if (TREE[I].L==TREE[I].R) return; Tree[i].mx=max (tree[i<<1].mx,tree[i<<1|1].mx); Tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;} void Push_down (int i) {if (TREE[I].L==TREE[I].R) return; if (tree[i].lazy) {update_same (i<<1,tree[i].mx); Update_same (i<<1|1,tree[i].mx); tree[i].lazy=0; }}void Build (int i,int l,int r) {tree[i].l=l; Tree[i].r=r; Tree[i]. lazy=0; if (l==r) {tree[i].mx=mex[l]; TREE[I].SUM=MEX[L]; Return } int mid= (L+R)/2; Build (I<<1,l,mid); Build (I<<1|1,mid+1,r); PUSH_UP (i);} void update (int i,int l,int R,int v) {if (L<=TREE[I].L&&R>=TREE[I].R) {update_same (i,v); Return } push_down (i); int mid= (TREE[I].L+TREE[I].R)/2; if (r<=mid) {update (I<<1,L,R,V); } else if (l>mid) {update (I<<1|1,L,R,V); } else {update (I<<1,L,MID,V); Update (I<<1|1,MID+1,R,V); } push_up (i);} int get_min_mx (int i,int v) {if (TREE[I].L==TREE[I].R) return TREE[I].L; if (TREE[I<<1].MX>V) return get_min_mx (I<<1,V); Return Get_min_mx (I<<1|1,V);} int main () {while (~SCANF ("%d", &n)) {if (n==0) break; 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]]=1; while (Mp.find (TMP)!=mp.end ()) tmp++; mex[i]=tmp; }/** for (int i=1;i<=n;i++) {printf (i==n? ") %d\n ":"%d ", mex[i]); }*/mp.clear (); for (int i=n; i>=1; i--) {if (Mp.find (A[i]) ==mp.end ()) next[i]=n+1; else Next[i]=mp[a[i]]; Mp[a[i]]=i; }/** for (int i=1;i<=n;i++) {printf (i==n? ") %d\n ":"%d ", next[i]); }*/build (1,1,n); LL sum=0; for (int i=1; i<=n; i++) {sum+=tree[1].sum; if (Tree[1].mx>a[i]) {int l=get_min_mx (1,a[i]); int r=next[i]; if (l<r) update (1,l,r-1,a[i]); } update (1,i,i,0); } printf ("%i64d\n", sum); } return 0;}
HDU 4747 Segment Tree