题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747
思路:
比赛打得太菜了,不想写。。。。线段树莽一下
实现代码:
#include<iostream> #include<cstdio> #include<map> #include<cmath> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid ll m = (l + r) >> 1 #define ll long long const ll M = 3e5+10; ll sum[M<<2],maxx[M<<2],lazy[M<<2],a[M],mex[M],n,Next[M]; map<ll,ll>mp; void pushup(ll rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; maxx[rt] = max(maxx[rt<<1] , maxx[rt<<1|1]); } void pushdown(ll rt,ll m){ if(lazy[rt]!=-1){ lazy[rt<<1] = lazy[rt]; lazy[rt<<1|1] = lazy[rt]; sum[rt<<1] = lazy[rt]*(m-(m>>1)); sum[rt<<1|1] = lazy[rt]*(m>>1); maxx[rt<<1] = lazy[rt]; maxx[rt<<1|1] = lazy[rt]; lazy[rt] = -1; } } void build(ll l,ll r,ll rt){ sum[rt] =0; maxx[rt] = 0; lazy[rt] = -1; if(l == r){ sum[rt] = mex[l]; maxx[rt] = mex[l]; return ; } mid; build(lson); build(rson); pushup(rt); } /*void ct(ll l,ll r,ll rt){ if(l == r){ cout << maxx[rt]<<" "; return ; } mid; ct(lson); ct(rson); }*/ void update(ll L,ll R,ll c,ll l,ll r,ll rt){ if(L <= l&&R >= r){ lazy[rt] = c; maxx[rt] = c; sum[rt] = c*(r-l+1); return ; } pushdown(rt,r-l+1); mid; //cout<<l<<" "<<r<<" "<<sum[1]<<endl; if(L <= m) update(L,R,c,lson); if(R > m) update(L,R,c,rson); pushup(rt); } ll query(ll p,ll l,ll r,ll rt){ if(l == r) return l; pushdown(rt,r-l+1); mid; //cout<<maxx[rt<<1]<<" "<<p<<endl; if(maxx[rt<<1] > p) return query(p,lson); else return query(p,rson); } int main() { while(scanf("%I64d",&n)&&n){ ll tmp = 0; mp.clear(); for(ll i = 1;i <= n;i ++){ scanf("%I64d",&a[i]); mp[a[i]] = 1; while(mp.find(tmp) != mp.end()) tmp++; mex[i] = tmp; } mp.clear(); for(ll 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; } build(1,n,1); ll ans = 0; for(ll i = 1;i <= n;i ++){ ans += sum[1]; if(maxx[1] > a[i]){ ll l = query(a[i],1,n,1); ll r = Next[i]; //cout<<l<<" "<<r<<endl; if(l < r) update(l,r-1,a[i],1,n,1); } update(i,i,0,1,n,1); } printf("%I64d ",ans); } return 0; }