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));
    		}
    	}
    }
    
  • 相关阅读:
    《大型网站技术架构》-读书笔记一:大型网站架构演化
    网站性能测试指标及网站压力测试
    PHP生成二维码
    数据结构与算法之PHP实现队列、栈
    数据结构与算法之PHP实现链表类(单链表/双链表/循环链表)
    PHP 堆 栈 数据段 代码段 存储的理解
    堆”,"栈","堆栈","队列"以及它们的区别
    c#加密
    Sequence contains no elements : LINQ error
    asp.net core2.0 连接mysql和mssql
  • 原文地址:https://www.cnblogs.com/suika/p/10204836.html
Copyright © 2011-2022 走看看