zoukankan      html  css  js  c++  java
  • BZOJ4695: 最假女选手

    BZOJ4695: 最假女选手

    https://lydsy.com/JudgeOnline/problem.php?id=4695

    分析:

    • 维护区间最小值,次小值,最小值个数,最大值,次大值,最大值个数,区间加标记,区间和。
    • 其中对于最小值增加的操作我们直接对当前结点的最小值修改。
    • 下传时如果儿子的最小值小于当前结点的最小值就修改掉,最大值同理。
    • 由于修改最小值时可能会影响最大值或次大值,顺便维护一下即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    using namespace std;
    #define N 500050
    #define ls p<<1
    #define rs p<<1|1
    typedef long long ll;
    int n,m,a[N];
    const int inf = 1<<30;
    int mn1[N<<2],mn2[N<<2],mx1[N<<2],mx2[N<<2],tag1[N<<2],tag2[N<<2],tag3[N<<2],cmn[N<<2],cmx[N<<2],len[N<<2];
    ll sum[N<<2];
    char buf[100000],*p1,*p2;
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
    int rd() {
    	int x=0,f=1; char s=nc();
    	while(s<'0'||s>'9') {if(s=='-')f=-1;s=nc();}
    	while(s>='0'&&s<='9') x=(((x<<2)+x)<<1)+s-'0',s=nc();
    	return x*f;
    }
    inline void pushup(int p) {
    	mn1[p]=min(mn1[ls],mn1[rs]);
    	if(mn1[ls]==mn1[rs]) mn2[p]=min(mn2[ls],mn2[rs]),cmn[p]=cmn[ls]+cmn[rs];
    	else if(mn1[ls]<mn1[rs]) mn2[p]=min(mn2[ls],mn1[rs]),cmn[p]=cmn[ls];
    	else mn2[p]=min(mn1[ls],mn2[rs]),cmn[p]=cmn[rs];
    	mx1[p]=max(mx1[ls],mx1[rs]);
    	if(mx1[ls]==mx1[rs]) mx2[p]=max(mx2[ls],mx2[rs]),cmx[p]=cmx[ls]+cmx[rs];
    	else if(mx1[ls]>mx1[rs]) mx2[p]=max(mx2[ls],mx1[rs]),cmx[p]=cmx[ls];
    	else mx2[p]=max(mx1[ls],mx2[rs]),cmx[p]=cmx[rs];
    	sum[p]=sum[ls]+sum[rs];
    }
    inline void giv1(int p,ll v) {
    	tag1[p]+=v; sum[p]+=len[p]*v;
    	mn1[p]+=v; mn2[p]+=v; mx1[p]+=v; mx2[p]+=v;
    }
    inline void giv2(int p,ll v) {
    	sum[p]+=cmn[p]*(v-mn1[p]);
    	if(mx1[p]==mn1[p]) mx1[p]=v;
    	if(mx2[p]==mn1[p]) mx2[p]=v;
    	mn1[p]=v;
    }
    inline void giv3(int p,ll v) {
    	sum[p]+=cmx[p]*(v-mx1[p]);
    	if(mn1[p]==mx1[p]) mn1[p]=v;
    	if(mn2[p]==mx1[p]) mn2[p]=v;
    	mx1[p]=v;
    }
    inline void pushdown(int p) {
    	if(tag1[p]) giv1(ls,tag1[p]),giv1(rs,tag1[p]),tag1[p]=0;
    	if(mn1[ls]<mn1[p]) giv2(ls,mn1[p]);
    	if(mn1[rs]<mn1[p]) giv2(rs,mn1[p]);
    	if(mx1[ls]>mx1[p]) giv3(ls,mx1[p]);
    	if(mx1[rs]>mx1[p]) giv3(rs,mx1[p]);
    }
    void build(int l,int r,int p) {
    	len[p]=r-l+1;
    	if(l==r) {
    		mn1[p]=mx1[p]=sum[p]=a[l]; cmn[p]=cmx[p]=1;
    		mn2[p]=inf; mx2[p]=-inf;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(l,mid,ls),build(mid+1,r,rs);
    	pushup(p);
    }
    void updadd(int l,int r,int x,int y,int v,int p) {
    	if(x<=l&&y>=r) {giv1(p,v); return ;}
    	int mid=(l+r)>>1; pushdown(p);
    	if(x<=mid) updadd(l,mid,x,y,v,ls);
    	if(y>mid) updadd(mid+1,r,x,y,v,rs);
    	pushup(p);
    }
    void updmax(int l,int r,int x,int y,int v,int p) {
    	if(mn1[p]>=v) return ;
    	if(x<=l&&y>=r&&mn2[p]>v) {giv2(p,v); return ;}	
    	if(l==r) {mn1[p]=mx1[p]=sum[p]=v; mn2[p]=inf; mx2[p]=-inf; return ;}
    	int mid=(l+r)>>1; pushdown(p);
    	if(x<=mid) updmax(l,mid,x,y,v,ls);
    	if(y>mid) updmax(mid+1,r,x,y,v,rs);
    	pushup(p);
    }
    void updmin(int l,int r,int x,int y,int v,int p) {
    	if(mx1[p]<=v) return ;
    	if(x<=l&&y>=r&&mx2[p]<v) {giv3(p,v); return ;}
    	if(l==r) {mn1[p]=mx1[p]=sum[p]=v; mn2[p]=inf; mx2[p]=-inf; return ;}
    	int mid=(l+r)>>1; pushdown(p);
    	if(x<=mid) updmin(l,mid,x,y,v,ls);
    	if(y>mid) updmin(mid+1,r,x,y,v,rs);
    	pushup(p);
    }
    ll get_s(int l,int r,int x,int y,int p) {
    	if(x<=l&&y>=r) return sum[p];
    	int mid=(l+r)>>1; pushdown(p); ll re=0;
    	if(x<=mid) re+=get_s(l,mid,x,y,ls);
    	if(y>mid) re+=get_s(mid+1,r,x,y,rs);
    	return re;
    }
    int rmq(int l,int r,int x,int y,int p,int o) {
    	if(x<=l&&y>=r) return o?mx1[p]:mn1[p];
    	int mid=(l+r)>>1,re=o?(-inf):inf; pushdown(p);
    	if(x<=mid) {
    		int t=rmq(l,mid,x,y,ls,o);
    		if(o) re=max(re,t);
    		else re=min(re,t);
    	}
    	if(y>mid) {
    		int t=rmq(mid+1,r,x,y,rs,o);
    		if(o) re=max(re,t);
    		else re=min(re,t);
    	}
    	return re;
    }
    int main() {
    	n=rd();
    	int i,opt,x,y,z;
    	for(i=1;i<=n;i++) a[i]=rd();
    	build(1,n,1);
    	m=rd();
    	while(m--) {
    		opt=rd(),x=rd(),y=rd();
    		if(opt==1) {
    			z=rd(); updadd(1,n,x,y,z,1);
    		}else if(opt==2) {
    			z=rd(); updmax(1,n,x,y,z,1);
    		}else if(opt==3) {
    			z=rd(); updmin(1,n,x,y,z,1);
    		}else if(opt==4) {
    			printf("%lld
    ",get_s(1,n,x,y,1));
    		}else if(opt==5) {
    			printf("%d
    ",rmq(1,n,x,y,1,1));
    		}else {
    			printf("%d
    ",rmq(1,n,x,y,1,0));
    		}
    	}
    }
    
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/suika/p/10204836.html
Copyright © 2011-2022 走看看