zoukankan      html  css  js  c++  java
  • [BZOJ4552][Tjoi2016&Heoi2016]排序(二分答案+线段树)

    二分答案mid,将>=mid的设为1,<mid的设为0,这样排序就变成了区间修改的操作,维护一下区间和即可

    然后询问第q个位置的值,为1说明>=mid,以上

    时间复杂度O(nlog2n)

    tips: 线段树操作区间[l,r]需满足l<=r,要特判;tag可能为0,要初始化为-1

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define N 100010
    using namespace std;
    
    struct info{int x,l,r;}q[N];
    int n,m,A[N],f[N],Ans,Q;
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    namespace Seg{
    	#define MID int mid=(l+r)>>1,ls=id<<1,rs=id<<1|1
    	int tag[N*4];
    	struct tree{int c[2];}T[N*4];
    	void pushup(int l,int r,int id){
    		MID;
    		T[id].c[0]=T[ls].c[0]+T[rs].c[0];
    		T[id].c[1]=T[ls].c[1]+T[rs].c[1];
    	}
    	void pushdown(int l,int r,int id){
    		int &tmp=tag[id];
    		if(tmp==-1)return;
    		MID;
    		tag[ls]=tag[rs]=tmp;
    		T[ls].c[tmp]=mid-l+1,T[ls].c[tmp^1]=0;
    		T[rs].c[tmp]=r-mid,T[rs].c[tmp^1]=0;
    		tmp=-1;
    	}
    	void build(int l,int r,int id){
    		if(l==r){
    			T[id].c[0]=(f[l]==0)?1:0;
    			T[id].c[1]=T[id].c[0]^1;
    			return;
    		}
    		MID;
    		build(l,mid,ls),build(mid+1,r,rs);
    		pushup(l,r,id);
    	}
    	int query(int l,int r,int id,int L,int R,int x){
    		if(L<=l&&r<=R)return T[id].c[x];
    		pushdown(l,r,id);
    		MID;
    		int res=0;
    		if(L<=mid)res+=query(l,mid,ls,L,R,x);
    		if(R>mid)res+=query(mid+1,r,rs,L,R,x);
    		return res;
    	}
    	void upd(int l,int r,int id,int L,int R,int x){
    		if(L<=l&&r<=R){
    			tag[id]=x;
    			T[id].c[x]=r-l+1,T[id].c[x^1]=0;
    			return;
    		}
    		pushdown(l,r,id);
    		MID;
    		if(L<=mid)upd(l,mid,ls,L,R,x);
    		if(R>mid)upd(mid+1,r,rs,L,R,x);
    		pushup(l,r,id);
    	}
    	void clr(){memset(tag,-1,sizeof(tag));}
    }using namespace Seg;
    
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;++i)A[i]=read();
    	for(int i=1;i<=m;++i)q[i].x=read(),q[i].l=read(),q[i].r=read();
    	Q=read();
    	for(int l=1,r=n;l<=r;){
    		int mid=(l+r)>>1;
    		for(int i=1;i<=n;++i)f[i]=(A[i]>=mid)?1:0;
    		clr(),build(1,n,1);
    		for(int i=1;i<=m;++i){
    			int L=q[i].l,R=q[i].r,x=q[i].x;
    			int cnt=query(1,n,1,L,R,x);
    			if(cnt)upd(1,n,1,L,L+cnt-1,x);
    			if(cnt<(R-L+1))upd(1,n,1,L+cnt,R,x^1);
    		}
    		if(query(1,n,1,Q,Q,1)==1) Ans=mid,l=mid+1;
    		else r=mid-1;
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    Linux命令:head
    Linux命令:less
    分布式锁的实现(java)
    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。(转载)
    SpringBoot实现热加载方式
    报表设计细节
    Pentaho Report Designer 数据大于某值显示红色
    Centos7更改yum源与更新系统
    Centos7安装配置NFS服务和挂载
    centos7上搭建ftp服务器(亲测可用)
  • 原文地址:https://www.cnblogs.com/void-f/p/9378533.html
Copyright © 2011-2022 走看看