[ABC237G] Range Sort Query

Problem Statement

Given is a permutation $P=(P_1,P_2,\ldots,P_N)$ of $1,2,\ldots,N$, and an integer $X$.

Additionally, $Q$ queries are given. The $i$-th query is represented as a triple of numbers $(C_i,L_i,R_i)$. Each query does the following operation on the permutation $P$.

  • If $C_i=1$: sort $P_{L_i},P_{L_i+1},\ldots,P_{R_i}$ in ascending order.
  • If $C_i=2$: sort $P_{L_i},P_{L_i+1},\ldots,P_{R_i}$ in descending order.

In the final permutation $P$ after executing all queries in the given order, find $i$ such that $P_i=X$.

Constraints

  • $1 \leq N \leq 2\times 10^5$
  • $1 \leq Q \leq 2\times 10^5$
  • $1 \leq X \leq N$
  • $(P_1,P_2,\ldots,P_N)$ is a permutation of $(1,2,\ldots,N)$.
  • $1 \leq C_i \leq 2$
  • $1 \leq L_i \leq R_i \leq N$
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

$N$ $Q$ $X$
$P_1$ $P_2$ $\ldots$ $P_N$
$C_1$ $L_1$ $R_1$
$C_2$ $L_2$ $R_2$
$\vdots$
$C_Q$ $L_Q$ $R_Q$

Output

Print the answer.


Sample Input 1

5 2 1
1 4 5 2 3
1 3 5
2 1 3

Sample Output 1

3

Initially, the permutation is $P=[1,4,5,2,3]$. The queries change it as follows.

  • $1$-st query sorts the $3$-rd through $5$-th elements in ascending order, making $P=[1,4,2,3,5]$.
  • $2$-nd query sorts the $1$-st through $3$-rd elements in descending order, making $P=[4,2,1,3,5]$.

In the final permutation, we have $P_3=1$, so $3$ should be printed.


Sample Input 2

7 3 3
7 5 3 1 2 4 6
1 1 7
2 3 6
2 5 7

Sample Output 2

7

The final permutation is $P=[1,2,6,5,7,4,3]$.

发现 \(x\) 一直是确定的,所以这么多数,其实在我们眼里,只有三种。大于 \(x\) 的,等于 \(x\) 的,小于 \(x\) 的。可以把他们分别标为 \(-1\),\(0\),\(1\)

可以用线段树去维护区间中 \(-1\) 的数量,\(0\) 的数量,\(1\) 的数量就好了。正着排序就是数区间中 \(-1,0,1\) 的数量,然后把用线段树区间覆盖去维护。如果更改到\(0\)的位置,那就更新维护答案。

#include<cstdio>
const int N=2e5+5;
int n,q,x,p,tag[N<<2],ret,op,l,r;
struct node{
	int cj,c0,c1;
	void operator=(const node&n){
		cj=n.cj;
		c0=n.c0;
		c1=n.c1;
	}
	node operator+(const node&n)const{
		return (node){cj+n.cj,c0+n.c0,c1+n.c1};
	}
}tr[N<<2];
void pushup(int o,int l,int r,int z)
{
	if(z==-1)
		tr[o].cj=r-l+1,tr[o].c0=tr[o].c1=0;
	else if(!z)
		tr[o].cj=tr[o].c1=0,tr[o].c0=1;
	else
		tr[o].c1=r-l+1,tr[o].cj=tr[o].c0=0;
	tag[o]=z;
}
void pushdown(int o,int l,int r)
{
	int md=l+r>>1;
	if(tag[o]==3)
		return;
	pushup(o<<1,l,md,tag[o]);
	pushup(o<<1|1,md+1,r,tag[o]);
	tag[o]=3;
}
void update(int o,int l,int r,int x,int y,int z)
{
	if(x>y)
		return;
	if(x<=l&&r<=y)
	{
		pushup(o,l,r,z);
		return;
	}
	int md=l+r>>1;
	pushdown(o,l,r);
	if(md>=x)
		update(o<<1,l,md,x,y,z);
	if(md<y)
		update(o<<1|1,md+1,r,x,y,z);
	tr[o]=tr[o<<1]+tr[o<<1|1];
}
node query(int o,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
		return tr[o];
	int md=l+r>>1;
	pushdown(o,l,r);
	node ret=(node){0,0,0};
	if(md>=x)
		ret=ret+query(o<<1,l,md,x,y);
	if(md<y)
		ret=ret+query(o<<1|1,md+1,r,x,y);
	return ret;
}
int main()
{
	scanf("%d%d%d",&n,&q,&x);
	for(int i=0;i<(N<<2);i++)
		tag[i]=3;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&p);
		if(p>x)
			update(1,1,n,i,i,1);
		else if(p==x)
			update(1,1,n,i,i,0),ret=i;
		else
			update(1,1,n,i,i,-1);
	}
	while(q--)
	{
		scanf("%d%d%d",&op,&l,&r);
		if(op==1)
		{
			node k=query(1,1,n,l,r);
			update(1,1,n,l,l+k.cj-1,-1);
			if(k.c0)
			{
				ret=l+k.cj;
				update(1,1,n,l+k.cj,l+k.cj,0);
			}
			update(1,1,n,r-k.c1+1,r,1);
		}
		else
		{
			node k=query(1,1,n,l,r);
			update(1,1,n,l,l+k.c1-1,1);
			if(k.c0)
			{
				ret=l+k.c1;
				update(1,1,n,l+k.c1,l+k.c1,0);
			}
			update(1,1,n,r-k.cj+1,r,-1);
		}
	}
		printf("%d\n",ret);
}
posted @ 2023-01-04 11:23  灰鲭鲨  阅读(48)  评论(0编辑  收藏  举报