• 【BZOJ4552】排序(线段树,二分答案)


    【BZOJ4552】排序(线段树,二分答案)

    题面

    BZOJ

    题解

    好神的题啊
    直接排序我们做不到
    怎么维护?
    考虑一下,如果我们随便假设一个答案
    怎么检验它是否成立?
    把这个数设成(1),其他的数字都设成(0)
    最后检查一下这个位置是不是(1)就好啦

    但是这样没法排序
    那么,我们考虑二分一个答案,
    把所有比(mid)大的数都设成(1)
    这样,如果在第(Q)位上的数字是(1)
    意味着有一个不小于当前(mid)的数在这个位置上
    否则就是一个比(mid)小的数在这个位置上
    这样就可以二分答案啦

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 222222
    #define lson (now<<1)
    #define rson (now<<1|1)
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Work{int l,r,opt;}p[MAX];
    int t[MAX<<2],tag[MAX<<2];
    int a[MAX],b[MAX],n,m,Q;
    void Build(int now,int l,int r)
    {
    	tag[now]=-1;
    	if(l==r){t[now]=b[l];return;}
    	int mid=(l+r)>>1;
    	Build(lson,l,mid);Build(rson,mid+1,r);
    	t[now]=t[lson]+t[rson];
    }
    void puttag(int now,int l,int r,int w)
    {
    	tag[now]=w;
    	t[now]=(r-l+1)*w;
    }
    void pushdown(int now,int l,int r)
    {
    	if(tag[now]==-1)return;
    	int mid=(l+r)>>1;
    	puttag(lson,l,mid,tag[now]);
    	puttag(rson,mid+1,r,tag[now]);
    	tag[now]=-1;
    }
    int Query(int now,int l,int r,int L,int R)
    {
    	if(L<=l&&r<=R)return t[now];
    	pushdown(now,l,r);
    	int ret=0,mid=(l+r)>>1;
    	if(L<=mid)ret+=Query(lson,l,mid,L,R);
    	if(R>mid)ret+=Query(rson,mid+1,r,L,R);
    	return ret;
    }
    void Modify(int now,int l,int r,int L,int R,int w)
    {
    	if(L<=l&&r<=R){puttag(now,l,r,w);return;}
    	pushdown(now,l,r);
    	int mid=(l+r)>>1;
    	if(L<=mid)Modify(lson,l,mid,L,R,w);
    	if(R>mid)Modify(rson,mid+1,r,L,R,w);
    	t[now]=t[lson]+t[rson];
    }
    void Work(int i)
    {
    	int ss=Query(1,1,n,p[i].l,p[i].r);
    	if(p[i].opt==0)
    	{
    		ss=p[i].r-p[i].l+1-ss;
    		if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,0);
    		if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,1);
    	}
    	else
    	{
    		if(ss!=0)Modify(1,1,n,p[i].l,p[i].l+ss-1,1);
    		if(ss!=p[i].r-p[i].l+1)Modify(1,1,n,p[i].l+ss,p[i].r,0);
    	}
    }
    bool check(int mid)
    {
    	for(int i=1;i<=n;++i)if(a[i]>=mid)b[i]=1;else b[i]=0;
    	Build(1,1,n);
    	for(int i=1;i<=m;++i)Work(i);
    	return Query(1,1,n,Q,Q);
    }
    int main()
    {
    	n=read();m=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<=m;++i)p[i].opt=read(),p[i].l=read(),p[i].r=read();
    	Q=read();
    	int l=1,r=n,ans=0;
    	while(l<=r)
    	{
    		int mid=(l+r)>>1;
    		if(check(mid))l=mid+1,ans=mid;
    		else r=mid-1;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Oracle对表解锁
    写txt文件在AIX5.3系统中乱码
    Spring Data JPA初使用
    简单流水号生成
    Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COER
    install Tcl8.5.10
    centOS下开机自启动apache、mysql、samba、svn等服务的最简单方法
    UNIX_SOCKET 进程间通信
    Linux(CentOS 5.5) Redis 安装及RedisPHP拓展安装应用
    python 返回 字典型结果集
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8468953.html
Copyright © 2020-2023  润新知