http://acm.hdu.edu.cn/showproblem.php?pid=5649
二分答案记为lim 将小于等于lim的数置为1 其余置为0 这样就可以处理排序操作 最后判一下目标位置处是否为1即可
二分的值越大 整个区间内的1数量越多 每次排序操作都会把1全部挪到左边或右边 1越多越有可能覆盖到目标位置 具有单调性
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node
{
int tp,l,r;
};
node order[maxn];
int sum[4*maxn],laz[4*maxn];
int ary[maxn];
int n,q,pos;
void change(int l,int r,int val,int cur)
{
sum[cur]=val*(r-l+1);
laz[cur]=val;
}
void pushup(int cur)
{
sum[cur]=sum[2*cur]+sum[2*cur+1];
}
void pushdown(int l,int r,int cur)
{
int m;
m=(l+r)/2;
if(laz[cur]!=-1){
change(l,m,laz[cur],2*cur);
change(m+1,r,laz[cur],2*cur+1);
laz[cur]=-1;
}
}
void build(int l,int r,int cur,int val)
{
int m;
laz[cur]=-1;
if(l==r){
if(ary[l]<=val) sum[cur]=1;
else sum[cur]=0;
return;
}
m=(l+r)/2;
build(l,m,2*cur,val);
build(m+1,r,2*cur+1,val);
pushup(cur);
}
int query(int pl,int pr,int l,int r,int cur)
{
int res,m;
if(pl<=l&&r<=pr){
return sum[cur];
}
pushdown(l,r,cur);
res=0,m=(l+r)/2;
if(pl<=m) res+=query(pl,pr,l,m,2*cur);
if(pr>m) res+=query(pl,pr,m+1,r,2*cur+1);
return res;
}
void update(int pl,int pr,int val,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr){
change(l,r,val,cur);
return;
}
pushdown(l,r,cur);
m=(l+r)/2;
if(pl<=m) update(pl,pr,val,l,m,2*cur);
if(pr>m) update(pl,pr,val,m+1,r,2*cur+1);
pushup(cur);
}
bool judge(int lim)
{
int res,i,j;
//printf("***%d***\n",lim);
build(1,n,1,lim);
/*
for(i=1;i<=n;i++){
printf("%d ",query(i,i,1,n,1));
}
printf("\n");
*/
for(i=1;i<=q;i++){
if(order[i].tp==0){
res=query(order[i].l,order[i].r,1,n,1);
if(res>0) update(order[i].l,order[i].l+res-1,1,1,n,1);
update(order[i].l+res,order[i].r,0,1,n,1);
}
else{
res=query(order[i].l,order[i].r,1,n,1);
res=order[i].r-order[i].l+1-res;
if(res>0) update(order[i].l,order[i].l+res-1,0,1,n,1);
update(order[i].l+res,order[i].r,1,1,n,1);
}
/*
for(j=1;j<=n;j++){
printf("%d ",query(j,j,1,n,1));
}
printf("\n");
*/
}
//printf("\n");
res=query(pos,pos,1,n,1);
return res;
}
int main()
{
int t,i,l,r,m,ans;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++){
scanf("%d",&ary[i]);
}
for(i=1;i<=q;i++){
scanf("%d%d%d",&order[i].tp,&order[i].l,&order[i].r);
}
scanf("%d",&pos);
l=1,r=n;
while(l<=r){
m=(l+r)/2;
if(judge(m)) r=m-1,ans=m;
else l=m+1;
}
printf("%d\n",ans);
}
return 0;
}