hdu 4747 Mex (2013 ACM/ICPC Asia Regional Hangzhou Online)

题目链接: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;
}
原文地址:https://www.cnblogs.com/kls123/p/9362389.html