[bzoj4552][Tjoi2016&Heoi2016]排序

这道题刚看的时候感觉不可做.

但是最后的询问只有一个这个限制很有用.

我们可以二分最后询问的答案,然后将序列转化为01序列,01序列的排序是可以用01的区间覆盖做的.

然后这道题就被解决了.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<iomanip>
#include<algorithm>
#include<map>
using namespace std;
#define LL long long
#define FILE "dealing"
#define up(i,j,n) for(int i=j;i<=n;++i)
#define db double
#define ull unsigned long long
#define eps 1e-10
#define pii pair<int,int>
int read(){
	int x=0,f=1,ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f*x;
}
const int maxn=400200,mod=(int)(1e9+7+0.1),limit=(int)(1e6+1);
int n,m;
int a[maxn];
int val[maxn],flag[maxn],f[maxn],siz[maxn];
int op[maxn],le[maxn],ri[maxn],q;
bool b[maxn];
void updata(int x){
	siz[x]=siz[x<<1]+siz[x<<1|1];
}
void fugai(int x,int d,int l,int r){
	flag[x]=1;
	f[x]=d;
	siz[x]=(r-l+1)*d;
}
void pushdown(int x,int l,int r){
	if(flag[x]){
		flag[x]=0;
		int mid=(l+r)>>1;
		fugai(x<<1,f[x],l,mid);
		fugai(x<<1|1,f[x],mid+1,r);
		f[x]=0;
	}
}
int L,R,key;
void change(int x,int l,int r){
	if(l>R||r<L)return;
	if(l>=L&&r<=R){
		fugai(x,key,l,r);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	change(x<<1,l,mid);
	change(x<<1|1,mid+1,r);
	updata(x);
}
void Change(int l,int r,int K){
	L=l,R=r,key=K;
	change(1,1,n);
}
void build(int x,int l,int r){
	if(l==r){
		siz[x]=b[l]?1:0;
		flag[x]=f[x]=0;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	updata(x);
}
int query(int x,int l,int r){
	if(l>R||r<L)return 0;
	if(l>=L&&r<=R)return siz[x];
	int mid=(l+r)>>1;
	pushdown(x,l,r);
	return query(x<<1,l,mid)+query(x<<1|1,mid+1,r);
}
int Query(int l,int r){L=l,R=r;return query(1,1,n);}
bool check(int mid){
	for(int i=1;i<=n;i++){
		if(a[i]<=mid)b[i]=0;
		else b[i]=1;
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		if(op[i]==0){
			int sum=ri[i]-le[i]+1,rcnt=Query(le[i],ri[i]),lcnt=sum-rcnt;
			Change(le[i],le[i]+lcnt-1,0);
			Change(ri[i]-rcnt+1,ri[i],1);
		}
		else {
			int sum=ri[i]-le[i]+1,rcnt=Query(le[i],ri[i]),lcnt=sum-rcnt;
			Change(le[i],le[i]+rcnt-1,1);
			Change(ri[i]-lcnt+1,ri[i],0);
		}
	}
	int sum=Query(q,q);
	if(sum==1)return 0;
	else return 1;
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	n=read(),m=read();
	up(i,1,n)a[i]=read();
	up(i,1,m){
		op[i]=read();
		le[i]=read(),ri[i]=read();
	}
	q=read();
	int left=1,right=n,ans=0;
	while(left<=right){
		int mid=(left+right)>>1;
		if(!check(mid))left=mid+1;
		else right=mid-1,ans=mid;
	}
	cout<<ans<<endl;
	return 0;
}

  

posted @ 2017-03-08 17:32  CHADLZX  阅读(136)  评论(0编辑  收藏  举报