HDU - 5306 Gorgeous Sequence 线段树 + 均摊分析

Code: 

#include<algorithm> 
#include<cstdio>
#include<cstring>         
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 2000000 
#define lson (now<<1) 
#define rson ((now<<1)|1)
using namespace std;       
int n,q;  
ll arr[maxn],mx[maxn<<2],se[maxn<<2],cnt[maxn<<2],sum[maxn<<2];      
void pushup(int l,int r,int now) {   
    int mid=(l+r)>>1; 
    int ls=lson,rs=(r>mid)?rson:0;       
    sum[now]=sum[ls]+sum[rs];   
    if(mx[ls]>mx[rs]) mx[now]=mx[ls],cnt[now]=cnt[ls],se[now]=max(se[ls],mx[rs]);         
    if(mx[rs]>mx[ls]) mx[now]=mx[rs],cnt[now]=cnt[rs],se[now]=max(se[rs],mx[ls]);    
    if(mx[ls]==mx[rs]) mx[now]=mx[ls],cnt[now]=cnt[ls]+cnt[rs],se[now]=max(se[ls],se[rs]);         
} 
void mark(int now,ll v) {
    if(v<mx[now]) sum[now]-=(mx[now]-v)*cnt[now], mx[now]=v; 
}
void pushdown(int l,int r,int now) {      
    int mid=(l+r)>>1;  
    mark(lson,mx[now]); 
    if(r>mid) mark(rson,mx[now]);     
}
void build(int l,int r,int now) {
    if(l==r) {
        mx[now]=arr[l],se[now]=-1,sum[now]=arr[l],cnt[now]=1;       
        return;               
    } 
    int mid=(l+r)>>1;    
    build(l,mid,lson); 
    if(r>mid) build(mid+1,r,rson);   
    pushup(l,r,now);    
}           
void change(int l,int r,int now,int L,int R,ll v) { 
    if(mx[now]<=v) return; 
    if(l>=L&&r<=R&&se[now]<v) {
        mark(now,v);    
        return;  
    }  
    pushdown(l,r,now);    
    int mid=(l+r)>>1;    
    if(L<=mid) change(l,mid,lson,L,R,v);  
    if(R>mid) change(mid+1,r,rson,L,R,v);     
    pushup(l,r,now);     
} 
ll qmax(int l,int r,int now,int L,int R) {
    if(l>=L&&r<=R) return mx[now];   
    pushdown(l,r,now); 
    int mid=(l+r)>>1; 
    ll re=-1;      
    if(L<=mid) re=max(re,qmax(l,mid,lson,L,R)); 
    if(R>mid) re=max(re,qmax(mid+1,r,rson,L,R));    
    return re;      
} 
ll qsum(int l,int r,int now,int L,int R) {
    if(l>=L&&r<=R) return sum[now];  
    pushdown(l,r,now);  
    int mid=(l+r)>>1;   
    ll re=0;  
    if(L<=mid) re+=qsum(l,mid,lson,L,R);   
    if(R>mid) re+=qsum(mid+1,r,rson,L,R);    
    return re;     
}
void solve() {
    scanf("%d%d",&n,&q); 
    for(int i=1;i<=n;++i) scanf("%lld",&arr[i]);  
    build(1,n,1);    
    while(q--) {
        int opt,x,y; 
        ll t; 
        scanf("%d%d%d",&opt,&x,&y); 
        if(opt==0) scanf("%lld",&t),change(1,n,1,x,y,t);           
        if(opt==1) printf("%lld\n",qmax(1,n,1,x,y)); 
        if(opt==2) printf("%lld\n",qsum(1,n,1,x,y));      
    }
}
int main() {
    // setIO("input");  
    int T; 
    scanf("%d",&T);        
    mx[0]=se[0]=-1;                   
    while(T--) solve();   
    return 0; 
}

  

posted @ 2019-07-23 09:27  EM-LGH  阅读(176)  评论(0编辑  收藏  举报