2017 ACM Arabella Collegiate Programming Contest-L. All’s Wall That Ends Wall

来源:互联网 发布:物联网域名注册 编辑:程序博客网 时间:2024/05/22 00:25

墙高:a数组。

预处理:先找到最高的墙壁的下标maxid,然后从左到maxid,从又到maxid进行遍历,可求出水柱高度w数组。

后面的更新:分3情况:(1):当前更新的点为最大值,记下标为pos,则找到除当前点的次大值的下标id,以a[id]为水柱高度更新(pos,id]或[id,pos),pos位置水柱高度为a[pos]。

(2):左边最大值大于a[pos],右边最大值小于a[pos],找到从右到左第一个大于a[pos]的下标l,更新(l,pos]。

(3):右边最大值大于a[pos],左边最大值小雨a[pos],找到从左到右第一个大于a[pos]的下标r,更新[pos,r)。

以上操作用线段树实现

#include"bits/stdc++.h"#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;typedef long long LL;const int maxn  = 1e5+7;const int inf = 0x3f3f3f3f;int a[maxn],w[maxn],n,q;LL sumh;struct node{    int ma,id,col;    LL w;}t[maxn<<2];void initial(int id){    int wh = 0;    for(int i = 1; i <= id; i++){        if(a[i] > wh) wh = a[i];        w[i] = wh;    }    wh = 0;    for(int i = n; i > id; i--){        if(a[i] > wh) wh = a[i];        w[i] = wh;    }}void pushupw(int rt){    t[rt].w = t[rt<<1].w + t[rt<<1|1].w;}void pushuph(int rt){    int lch = rt<<1, rch = rt<<1|1;    if(t[lch].ma >= t[rch].ma){        t[rt].ma = t[lch].ma;        t[rt].id = t[lch].id;    }    else{        t[rt].ma = t[rch].ma;        t[rt].id = t[rch].id;    }}void pushdown(int l, int r, int rt){    if(!t[rt].col) return;    int mid = l+r>>1;    t[rt<<1].w  = (LL) t[rt].col*(mid-l+1);    t[rt<<1|1].w = (LL) t[rt].col*(r-mid);    t[rt<<1].col = t[rt<<1|1].col = t[rt].col;    t[rt].col = 0;}void build(int l = 1,  int r = n, int rt = 1){    t[rt].col = 0;    if(l == r){        t[rt].id = l;        t[rt].w = w[l];        t[rt].ma = a[l];        return;    }    int mid = l+r>>1;    build(lson);    build(rson);    pushupw(rt);    pushuph(rt);}void addh(int pos, int l = 1, int r = n, int rt = 1){    if(l == r){        t[rt].ma = a[l];        return;    }    int mid = l+r>>1;    if(pos <= mid) addh(pos,lson);    else addh(pos,rson);    pushuph(rt);}void addw(int L, int R, int val, int l = 1,  int r = n, int rt = 1){    if(L <= l && r <= R){        t[rt].col = val;        t[rt].w = (LL) val*(r-l+1);        return;    }    pushdown(l,r,rt);    int mid = l+r>>1;    if(L <= mid) addw(L,R,val,lson);    if(mid < R) addw(L,R,val,rson);    pushupw(rt);}int qmax(int L, int R,  int l = 1,  int r = n, int rt = 1){    if(L <= l && r <= R){        return t[rt].id;    }    int mid = l+r>>1, ret = 0;    if(L <= mid){        int i = qmax(L,R,lson);        ret = a[i] > a[ret]? i : ret;    }    if(mid  < R){        int i = qmax(L,R,rson);        ret = a[i] > a[ret]? i : ret;    }    return ret;}int getidl(int val ,int l = 1,  int r = n, int rt = 1){    if(l == r){        return l;    }    int mid = l+r>>1;    if(t[rt<<1|1].ma > val) return getidl(val,rson);    else return getidl(val,lson);}int getidr(int val, int l = 1,  int r = n, int rt = 1){    if(l == r){        return l;    }    int mid = l+r>>1;    if(t[rt<<1].ma > val) return getidr(val,lson);    else return getidr(val,rson);}void update(int pos){    addh(pos);    int idl = 0, idr = 0;    if(pos > 1) idl = qmax(1,pos-1);    if(pos < n) idr = qmax(pos+1,n);    if(a[idl] <= a[pos] && a[idr] <= a[pos]){        if(a[idl] > a[idr]){            addw(idl,pos-1,a[idl]);        }        else{            addw(pos+1,idr,a[idr]);        }        addw(pos,pos,a[pos]);    }    else if(a[idl] < a[pos]){        int r = getidr(a[pos]);        addw(pos,r-1,a[pos]);    }    else if(a[idr] < a[pos]){        int l = getidl(a[pos]);        addw(l+1,pos,a[pos]);    }}int main(){#ifdef __LOCAL__    //freopen("input.txt","r",stdin);    //freopen("out2.txt","w",stdout);#endif // _LOCAL__    int T;    scanf("%d",&T);    while(T--){        sumh = 0;        int maid = 0;        scanf("%d%d",&n,&q);        a[0] = a[n+1] = 0;        for(int i = 1; i<= n; i++){            scanf("%d",&a[i]);            sumh += a[i];            if(a[i] > a[maid]) maid = i;        }        initial(maid);        build();        for(int i = 1,pos,x; i <= q; i++){            char ch;            scanf("\n%c",&ch);            if(ch == 'U'){                scanf("%d%d",&pos,&x);                a[pos] += x;                sumh += x;                update(pos);            }            else{                cout<<t[1].w-sumh<<endl;            }        }    }    return 0;}


阅读全文
0 0
原创粉丝点击