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$. In the final permutation $P$ after executing all queries in the given order, find $i$ such that $P_i=X$.Problem Statement
Constraints
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);
}
标签:Sort,ABC237G,update,ret,leq,Range,permutation,query,ldots
From: https://www.cnblogs.com/mekoszc/p/17024366.html