P2824 [HEOI2016/TJOI2016]排序

题目:P2824 [HEOI2016/TJOI2016]排序

思路:

线段树专题讲的。
讲过不只一次了,方法挺巧妙的。

这道题并不是真的需要使用线段树来做排序。
• 考虑这道题的特殊性质,发现我们只需要求最后一个元素的大小。
• 由于是全排列,我们可以直接二分答案x,将排列中大于等于x的标记为1,小于x的元素标记为0,维护一颗支持区间覆盖、查询区间和的线段树。每次排序时,查询区间中0、1的个数,之后若是升序排列将前面一段覆盖成0、后一段覆盖成1,降序排列则是反过来。
• 完成操作后,只需查询所需位置的权值即可完成二分的检验工作,总
复杂度(O(nlog^2n))

在线算法先咕着,以后再填。


Code:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,pos,a[N],b[N];
struct data{
	int type,l,r;
}q[N];
struct Tree{
	int l,r,sum,tag;
#define l(p) (node[p].l)
#define r(p) (node[p].r)
#define sum(p) (node[p].sum)
#define tag(p) (node[p].tag)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
}node[N<<2];
void build(int p,int l,int r){
	l(p)=l;r(p)=r;tag(p)=-1;
	if(l==r) return (void) (sum(p)=b[l]);
	int mid=(l(p)+r(p))>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	sum(p)=sum(ls(p))+sum(rs(p));
}
void upd(int p,int v){
	tag(p)=v;
	sum(p)=(r(p)-l(p)+1)*v;
}
void pdown(int p){
	if(tag(p)!=-1){
		upd(ls(p),tag(p));
		upd(rs(p),tag(p));
		tag(p)=-1;
	}
}
int query(int p,int L,int R){
	if(l(p)>R||r(p)<L) return 0;
	if(L<=l(p)&&r(p)<=R) return sum(p);
	pdown(p);
	return query(ls(p),L,R)+query(rs(p),L,R);
}
void Set(int p,int L,int R,int v){
	if(l(p)>R||r(p)<L) return;
	if(L<=l(p)&&r(p)<=R) return upd(p,v);
	pdown(p);
	Set(ls(p),L,R,v);
	Set(rs(p),L,R,v);
	sum(p)=sum(ls(p))+sum(rs(p));
}
bool check(int mid){
	for(int i=1;i<=n;++i) b[i]=(a[i]>=mid);
	build(1,1,n);
	for(int i=1;i<=m;++i){
		int cnt=query(1,q[i].l,q[i].r);
		int len=q[i].r-q[i].l+1;
		if(q[i].type==0) Set(1,q[i].l,q[i].l+len-cnt-1,0),Set(1,q[i].l+len-cnt,q[i].r,1);
		else Set(1,q[i].l,q[i].l+cnt-1,1),Set(1,q[i].l+cnt,q[i].r,0);
	}
	return query(1,pos,pos); 
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	for(int i=1;i<=m;++i) scanf("%d%d%d",&q[i].type,&q[i].l,&q[i].r);
	scanf("%d",&pos);
	int l=1,r=n,ans=1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(mid)) ans=max(ans,mid),l=mid+1;
		else r=mid-1;
	}
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/yu-xing/p/11253057.html