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

匿名 (未验证) 提交于 2019-12-02 23:49:02

#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;  } 

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!