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