• AtCoder Beginner Contest 237 G Range Sort Query


    题目传送门

    题目大意

    一个1~n的排列,进行m区间升/降序排序操作,问x最终所在的位置。

    思路

    这道题不复杂,但不好想,还容易想到一些没用的方法(如平衡树)。

    我们尝试换个思路,我们要找的这个位置的值满足>=x且不满足>=x+1

    这看起来是废话(与=x完全等价),但是可以拆分上面两个限制条件,将排列变为两个只含0/1的序列,最终满足一个为0一个为1的位置就是答案。

    这样,区间排序就很容易了,我们只在乎0/1,不在乎取值,0和1各自放一起,直接用线段树维护就好。

    具体来说,查找区间内0/1个数,前面放0/1,后面放1/0,即为排序。

    #include<bits/stdc++.h>
    #define mid ((l+r)>>1)
    #define inf 1000000007
    using namespace std;
    int n,m,T,pos;
    struct node
    {
    	int t[1000005][2],tag[1000005];
    	void build(int l,int r,int k)
    	{
    		t[k][0]=r-l+1;
    		if(l==r)return;
    		build(l,mid,k*2);
    		build(mid+1,r,k*2+1);
    	}
    	void pushdown(int l,int r,int k)
    	{
    		int v=tag[k];
    		if(!v)return;
    		tag[k*2]=tag[k*2+1]=v;
    		v--;
    		t[k*2][v]=mid-l+1,t[k*2][v^1]=0;
    		t[k*2+1][v]=r-mid,t[k*2+1][v^1]=0;
    		tag[k]=0;
    	}
    	void fix(int l,int r,int k,int x,int y,int v)
    	{
    		if(x>y)return;
    		if(l<r)pushdown(l,r,k);
    		if(l==x&&r==y)
    		{
    			t[k][v]=r-l+1,t[k][v^1]=0;
    			if(l<r)tag[k]=v+1;
    			return;
    		}
    		if(y<=mid)fix(l,mid,k*2,x,y,v);
    		else if(x>mid)fix(mid+1,r,k*2+1,x,y,v);
    		else fix(l,mid,k*2,x,mid,v),fix(mid+1,r,k*2+1,mid+1,y,v);
    		t[k][0]=t[k*2][0]+t[k*2+1][0];
    		t[k][1]=t[k*2][1]+t[k*2+1][1];
    	}
    	int find(int l,int r,int k,int x,int y,int v)
    	{ 
    		if(l<r)pushdown(l,r,k);
    		if(l==x&&r==y)
    		{
    			return t[k][v];
    		}
    		if(y<=mid)return find(l,mid,k*2,x,y,v);
    		else if(x>mid)return find(mid+1,r,k*2+1,x,y,v);
    		else return find(l,mid,k*2,x,mid,v)+find(mid+1,r,k*2+1,mid+1,y,v);
    		t[k][0]=t[k*2][0]+t[k*2+1][0];
    		t[k][1]=t[k*2][1]+t[k*2+1][1];
    	}
    	void rev(int l,int r,int k)
    	{
    		int mad=find(1,n,1,l,r,k);
    		fix(1,n,1,l,l+mad-1,k);
    		fix(1,n,1,l+mad,r,k^1);
    	}
    }ta,tb;
    long long read()
    {
    	long long 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<<1)+(x<<3)+ch-48,ch=getchar();
    	return x*f;
    }
    void calc(int l,int r,int k)
    {
    	if(l==r)
    	{
    		if(ta.t[k][0]^tb.t[k][0])
    		{
    			pos=l;
    		}
    		return;
    	}
    	ta.pushdown(l,r,k);
    	tb.pushdown(l,r,k);
    	calc(l,mid,k*2);
    	calc(mid+1,r,k*2+1);
    }
    int main()
    {
    	n=read(),m=read(),T=read();
    	ta.build(1,n,1);
    	tb.build(1,n,1);
    	for(int i=1,x;i<=n;i++)
    	{
    		x=read();
    		if(x>=T)
    		{
    			ta.fix(1,n,1,i,i,1);
    		}
    		if(x>=T+1)
    		{
    			tb.fix(1,n,1,i,i,1);
    		}
    	}
    	for(int i=1,opt,l,r;i<=m;i++)
    	{
    		opt=read(),l=read(),r=read();
    		ta.rev(l,r,opt-1);
    		tb.rev(l,r,opt-1);
    	}
    	calc(1,n,1);
    	printf("%d\n",pos);
    	return 0;
    }
    
  • 相关阅读:
    用Zend Studio12 导入在workspace中的项目
    PHP 统计中文字符串的长度
    jQuery判断checkbox是否选中的3种方法
    js,jquery获取下拉框选中的option
    HTML与XHTML的区别
    HTML头部
    HTML框架标签
    js的继承
    图片懒加载
    Http请求的gzip压缩
  • 原文地址:https://www.cnblogs.com/HYDcn666/p/abc237g.html
Copyright © 2020-2023  润新知