• BZOJ4552 [Tjoi2016&Heoi2016]排序


    BZOJ4552 [Tjoi2016&Heoi2016]排序


    题目描述

    传送门

    题目分析

    对于一个排列直接找明显不现实,考虑将其转化成一个比较容易计算的排列上去。

    明显对于一个(01)序列,我们进行如上操作是很容易的,首先计算区间内(1)的个数(cnt),然后以升序排列为例,我们将([L,R-cnt])的部分区间覆盖为(0),将([R-cnt+1,R])的部分区间覆盖为(1)就可以了。

    发现只有一组询问,考虑二分。

    可以二分一个数,然后将比这个数小的置为(0),其余的置为(1)。然后对这个数列进行(check)。如果最后这个位置上是(1)就说明答案要更大,否则更小。

    是代码呢

    #include <bits/stdc++.h>
    using namespace std;
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    #define mid ((l+r)>>1)
    const int MAXN=2e5+7;
    int sum[MAXN],tag[MAXN],b[MAXN],n,m,Q,a[MAXN],ans;
    struct po{
    	int opt,l,r;
    }q[MAXN];
    inline void pushup(int rt){sum[rt]=sum[ls]+sum[rs];}
    inline void pushdown(int l,int r,int rt)
    {
    	if(tag[rt]!=-1){
    		sum[ls]=(mid-l+1)*tag[rt];
    		sum[rs]=(r-mid)*tag[rt];
    		tag[ls]=tag[rs]=tag[rt];
    		tag[rt]=-1;
    	}
    }
    inline void build(int l,int r,int rt)
    {
    	tag[rt]=-1;
    	if(l==r){
    		sum[rt]=b[l];return;
    	}
    	build(l,mid,ls);build(mid+1,r,rs);
    	pushup(rt);
    }
    inline void update(int L,int R,int k,int l,int r,int rt){
    	if(L<=l&&r<=R){
    		sum[rt]=(r-l+1)*k;tag[rt]=k;
    		return;
    	}
    	pushdown(l,r,rt);
    	if(L<=mid) update(L,R,k,l,mid,ls);
    	if(R>mid) update(L,R,k,mid+1,r,rs);
    	pushup(rt);
    }
    inline int query(int L,int R,int l,int r,int rt)
    {
    	if(l>R||r<L) return 0;
    	pushdown(l,r,rt);
    	if(L<=l&&r<=R) return sum[rt];
    	return query(L,R,l,mid,ls)+query(L,R,mid+1,r,rs);
    }
    inline int check(int x)
    {
    	for(int i=1;i<=n;i++) b[i]=(a[i]>=x)?1:0;
    	build(1,n,1);
    	for(int i=1;i<=m;i++){
    		int cnt=query(q[i].l,q[i].r,1,n,1);
    //		cout<<q[i].l<<" "<<q[i].r<<endl;
    		if(q[i].opt==0){
    			if(cnt!=q[i].r-q[i].l+1)update(q[i].l,q[i].r-cnt,0,1,n,1);
    			if(cnt>0)update(q[i].r-cnt+1,q[i].r,1,1,n,1);
    		} else {
    			if(cnt>0)update(q[i].l,q[i].l+cnt-1,1,1,n,1);
    			if(cnt!=q[i].r-q[i].l+1)update(q[i].l+cnt,q[i].r,0,1,n,1);
    		}
    	}
    	int d=query(Q,Q,1,n,1);
    	return d;
    }
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int main()
    {
    	n=read();m=read();
    	for(int i=1;i<=n;i++) a[i]=read();
    	for(int i=1;i<=m;i++) {int opt=read(),x=read(),y=read();q[i]=(po){opt,x,y};}
    	Q=read();
    	int l=1,r=n;
    	while(l<=r){
    		if(check(mid))l=mid+1; 
    		else r=mid-1,ans=mid;
    	}
    	cout<<l-1;
    }
    
  • 相关阅读:
    VS.NET的新用途
    ASP.NET缓存引起的问题
    增加了查看最新回复功能
    高级浏览功能可以使用了
    转载JGTM'2004 [MVP]的文章
    首页文章字数统计改进
    请推荐好的工作流产品
    不错的工具:Reflector for .NET
    寻找文件同步软件
    javascript引起博客园首页不能显示问题说明
  • 原文地址:https://www.cnblogs.com/victorique/p/10302212.html
Copyright © 2020-2023  润新知