# HDU 4747 Mex

1.如果M(1,r)<x[1]，那么去掉后M(1,r)变成M(2,r)，且值不变。

2.如果M(1,r)>x[1]，且区间[2,r]中不存在x[1]，那么去掉后M(2,r)=x[1]。

code：

#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <set>
#include <map>
using namespace std;

/*-------------------------Template----*/
#define N  200020
#define E  100010
#define ll long long
#define CUBE(x) ((x)*(x)*(x))
#define SQ(x)     ((x)*(x))
#define ALL(x)     x.begin(),x.end()
#define CLR(x,a) memset(x,a,sizeof(x))
#define maxAry(a,n) max_element(a,a+(n))
#define minAry(a,n) min_element(a,a+(n))
typedef pair<int,int> PI;
const int INF=0x3fffffff;
const int PRIME =999983;
const int MOD   =10007;
const int MULTI =1000000007;
const double EPS=1e-9;
const int dx[]  = {0, 1, 0, -1};
const int dy[]  = {1, 0, -1, 0};
inline bool isodd(int x){return x&1;}
/*----------------------end Template----*/

class segTree{
#define lson (rt<<1)
#define rson (rt<<1|1)
#define rtl seg[rt].l
#define rtr seg[rt].r
private:
struct segment{
int l,r,max,mark;
ll sum;
}seg[N<<2];
public:
void setVal(int val,int rt)
{
seg[rt].sum=1ll*(rtr-rtl+1)*val;
seg[rt].max=seg[rt].mark=val;
}
void pushup(int rt)
{
seg[rt].sum=seg[lson].sum+seg[rson].sum;
seg[rt].max=max(seg[lson].max,seg[rson].max);
}
void pushdown(int rt)
{
if(seg[rt].mark!=-1){
setVal(seg[rt].mark,lson);
setVal(seg[rt].mark,rson);
seg[rt].mark=-1;
}
}
void update(int val,int L,int R,int rt)
{
if(L<=rtl && rtr<=R){
setVal(val,rt);
return ;
}
int mid=(rtl+rtr)>>1;
pushdown(rt);
if(L<=mid) update(val,L,R,lson);
if(mid<R) update(val,L,R,rson);
pushup(rt);
}
ll query(int L,int R,int rt)
{
ll ans=0;
if(L<=rtl && rtr<=R)
return seg[rt].sum;
int mid=(rtl+rtr)>>1;
pushdown(rt);
if(L<=mid) ans+=query(L,R,lson);
if(mid<R) ans+=query(L,R,rson);
return ans;
}
int up_bound(int val,int rt)
{
if(rtl==rtr){
if(seg[rt].max<val) return -1;
return rtl;
}
pushdown(rt);
if(val<seg[lson].max)
return up_bound(val,lson);
else
return up_bound(val,rson);
}
void build(int l,int r,int rt)
{
rtl=l, rtr=r;
seg[rt].mark=-1;
if(l==r) return;
int mid=(rtl+rtr)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
}
}T;

int n,a[N],d[N],Next[N];
bool vis[N];

int main()
{
int mex;
ll ans;
while(scanf("%d",&n),n){
CLR(vis,0);
mex=ans=0;
T.build(1,n,1);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]=a[i]>n?n+1:a[i];
vis[a[i]]=true;
if(a[i]==mex)
for(int j=mex+1;j<=n;j++) if(!vis[j]){
mex=j; break;
}
T.update(mex,i,i,1);
ans+=mex;
}
CLR(d,-1);
for(int i=n;i>=1;i--){
if(d[a[i]]==-1) Next[i]=n+1;
else Next[i]=d[a[i]];
d[a[i]]=i;
}
for(int i=2;i<=n;i++){
int l=T.up_bound(a[i-1],1);
if(l!=-1) T.update(a[i-1],l,Next[i-1]-1,1);
ans+=T.query(i,n,1);
}
printf("%I64d\n", ans);
}
return 0;
}