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

    传送门

    题目大意

    维护一个序列,支持区间加,区间取$max,min$,区间求和,区间求最大最小值。

    题解

    区间取$max,min$必然要用到神奇的吉老师线段树,即维护区间最大值、最大值数量,次大值来剪枝。

    即,当取$min$介于最大值和次大值之间时进行修改,否则暴力递归子树。

    区间取$max$同理。

    这道题还要套上区间加和区间求和,所以$pushdown$的时候还是比较麻烦的,注意要特殊处理最大值等于最小值或最大值等于严格次小值的情况。

    复杂度据说是$O(Nlog^2N)$吧,反正我不会证

    然而实际上跑的很快,虽然我的代码T掉了嘤嘤嘤

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define mid ((l+r)>>1)
    #define M 800010
    #define INF 2000000000
    using namespace std;
    int read(){
    	int nm=0,fh=1; int cw=getchar();
    	for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
    	for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    	return nm*fh;
    }
    void write(LL x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar((int)(x%10+'0'));}
    LL p[M<<1],ans;
    int tg[M<<1],mx[M<<1],mn[M<<1],sx[M<<1],sn[M<<1],A[M],cx[M<<1],cn[M<<1];
    int n,m,T,L[M<<1],R[M<<1],cnt,u[M],v[M],dt[M],t[M],Rt;
    inline void pushup(int x){
    	int ls=L[x],rs=R[x]; p[x]=p[ls]+p[rs];
    	if(mx[ls]>mx[rs]) mx[x]=mx[ls],cx[x]=cx[ls],sx[x]=max(mx[rs],sx[ls]);
    	if(mx[ls]<mx[rs]) mx[x]=mx[rs],cx[x]=cx[rs],sx[x]=max(mx[ls],sx[rs]);
    	if(mx[ls]==mx[rs]) mx[x]=mx[ls],cx[x]=cx[ls]+cx[rs],sx[x]=max(sx[ls],sx[rs]);
    	if(mn[ls]<mn[rs]) mn[x]=mn[ls],cn[x]=cn[ls],sn[x]=min(mn[rs],sn[ls]);
    	if(mn[ls]>mn[rs]) mn[x]=mn[rs],cn[x]=cn[rs],sn[x]=min(mn[ls],sn[rs]);
    	if(mn[ls]==mn[rs]) mn[x]=mn[ls],cn[x]=cn[ls]+cn[rs],sn[x]=min(sn[ls],sn[rs]);
    }
    inline void inc(int x,LL len,int dt){tg[x]+=dt,mx[x]+=dt,mn[x]+=dt,sx[x]+=dt,sn[x]+=dt,p[x]+=len*((LL)dt);}
    inline void upmin(int num,int y){
    	if(mx[y]==mn[y]) mn[y]=num; if(mx[y]==sn[y]) sn[y]=num;
    	p[y]+=(LL)(num-mx[y])*((LL)cx[y]),mx[y]=num;
    }
    inline void upmax(int num,int y){
    	if(mx[y]==mn[y]) mx[y]=num; if(mn[y]==sx[y]) sx[y]=num;
    	p[y]+=(LL)(num-mn[y])*((LL)cn[y]),mn[y]=num;
    }
    inline void pushdown(int x,int l,int r){
    	int ls=L[x],rs=R[x]; LL lm=(mid-l+1),rm=(r-mid);
    	if(tg[x]) inc(ls,lm,tg[x]),inc(rs,rm,tg[x]),tg[x]=0;
    	if(mx[x]<mx[ls]) upmin(mx[x],ls); if(mx[x]<mx[rs]) upmin(mx[x],rs);
    	if(mn[x]>mn[ls]) upmax(mn[x],ls); if(mn[x]>mn[rs]) upmax(mn[x],rs);
    }
    void build(int &x,int l,int r){
    	x=++cnt;
    	if(l==r){p[x]=mx[x]=mn[x]=A[l],cx[x]=cn[x]=1;sx[x]=-INF,sn[x]=INF;return;}
    	build(L[x],l,mid),build(R[x],mid+1,r),pushup(x);
    }
    LL qry(int x,int l,int r,int ls,int rs,int typ){
    	if(rs<l||r<ls){return typ==4?0:(typ==5?-INF:INF);}
    	if(ls<=l&&r<=rs){return typ==4?p[x]:(typ==5?mx[x]:mn[x]);}
    	pushdown(x,l,r); LL t1=qry(L[x],l,mid,ls,rs,typ);
    	LL t2=qry(R[x],mid+1,r,ls,rs,typ); pushup(x);
    	return typ==4?t1+t2:(typ==5?max(t1,t2):min(t1,t2));
    }
    void add(int x,int l,int r,int ls,int rs,int dx){
    	if(r<ls||rs<l) return;
    	if(ls<=l&&r<=rs){inc(x,r-l+1,dx);return;}
    	pushdown(x,l,r),add(L[x],l,mid,ls,rs,dx);
    	add(R[x],mid+1,r,ls,rs,dx),pushup(x);
    }
    void mdf(int x,int l,int r,int ls,int rs,int typ,int dx){
    	if(r<ls||rs<l||(typ==2&&mn[x]>=dx)||(typ==3&&mx[x]<=dx)) return;
    	if(ls<=l&&r<=rs&&((typ==2&&sn[x]>dx)||(typ==3&&sx[x]<dx))){
    		if(typ==2) upmax(dx,x);else upmin(dx,x); return;
    	}
    	pushdown(x,l,r),mdf(L[x],l,mid,ls,rs,typ,dx);
    	mdf(R[x],mid+1,r,ls,rs,typ,dx),pushup(x);
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++) A[i]=read(); build(Rt,1,n);
    	for(int T=read(),tpe,ls,rs,dx;T;--T){
    		tpe=read(),ls=read(),rs=read();
    		if(tpe>3) ans=qry(Rt,1,n,ls,rs,tpe),write(ans),putchar('
    ');
    		else if(tpe>1) dx=read(),mdf(Rt,1,n,ls,rs,tpe,dx);
    		else dx=read(),add(Rt,1,n,ls,rs,dx);
    	}
    	return 0;
    }
  • 相关阅读:
    linux tcp调优
    nginx 代理http配置实例
    nginx代理socket tcp/udp
    C++对象数组初始化
    《大型网站技术架构》读书笔记
    内核空间、用户空间和虚拟地址(转)
    集群——LVS理论(转)
    Linux服务器集群系统(一)(转)
    从一个开发的角度看负载均衡和LVS(转)
    ubuntu下允许root用户ssh远程登录
  • 原文地址:https://www.cnblogs.com/OYJason/p/9756318.html
Copyright © 2011-2022 走看看