HDU 5306 Gorgeous Sequence

传送门

题解传送门

吉司机线段树。

奥妙重重。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
const int N=1e6+7;
typedef long long LL;
using namespace std;
int T,n,m,mx[N<<2],cd[N<<2],a[N],c[N];
LL sum[N<<2];

template<typename T> void read(T &x) {
    T f=1; x=0; char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
void update(int x) {
    mx[x]=max(mx[lc],mx[rc]);
    cd[x]=max(cd[lc],cd[rc]); c[x]=0;
    if(mx[lc]!=mx[rc]) cd[x]=max(cd[x],min(mx[lc],mx[rc]));
    if(mx[lc]==mx[x]) c[x]+=c[lc];
    if(mx[rc]==mx[x]) c[x]+=c[rc];
    sum[x]=sum[lc]+sum[rc];
}

void get_min(int x,int v) {
    if(mx[x]<=v) return;
    sum[x]=sum[x]+(LL)(v-mx[x])*c[x]; mx[x]=v; 
} 

void down(int x,int l,int r) {
    if(l==r) return;
    get_min(lc,mx[x]);
    get_min(rc,mx[x]);
} 

void build(int x,int l,int r) {
    if(l==r) { c[x]=1; mx[x]=sum[x]=a[l]; cd[x]=-1; return;}
    build(lc,l,mid); build(rc,mid+1,r);
    update(x);
}

void change(int x,int l,int r,int ql,int qr,int t) {
    if(t>=mx[x]) return;
    if(l>=ql&&r<=qr&&t>cd[x]) {
        get_min(x,t);
        return ;
    }
    down(x,l,r);
    if(ql<=mid) change(lc,l,mid,ql,qr,t);
    if(qr>mid) change(rc,mid+1,r,ql,qr,t);
    update(x); 
}

LL qry(int x,int l,int r,int ql,int qr,int o) {
    if(l>=ql&&r<=qr) return o==1?mx[x]:sum[x];
    down(x,l,r);
    if(qr<=mid) return qry(lc,l,mid,ql,qr,o);
    if(ql>mid) return qry(rc,mid+1,r,ql,qr,o);
    if(o==1) return max(qry(lc,l,mid,ql,qr,o),qry(rc,mid+1,r,ql,qr,o));
    else return qry(lc,l,mid,ql,qr,o)+qry(rc,mid+1,r,ql,qr,o);
} 

int main() {
    read(T);
    while(T--) {
        read(n); read(m); 
        for(int i=1;i<=n;i++) read(a[i]);
        build(1,1,n);
        while(m--) {
            int o,x,y,t;
            read(o); read(x); read(y);
            if(o==0) {
                read(t);
                change(1,1,n,x,y,t);
            }
            else if(o==1) printf("%lld\n",qry(1,1,n,x,y,1));
            else printf("%lld\n",qry(1,1,n,x,y,0));
        }
    }
    return 0;
}
View Code

 

posted @ 2018-01-18 22:09  啊宸  阅读(182)  评论(0编辑  收藏  举报