Description
给出一个到的全排列,现在对这个全排列序列进行次局部排序,排序分为种:
表示将区间的数字升序排序;
表示将区间的数字降序排序.
最后询问第位置上的数字.
Input
第行为两个整数和.表示序列的长度,表示局部排序的次数.
第行为个整数,表示到的一个全排列.
接下来输入行,每行有个整数
为代表升序排序,为1代表降序排序;表示排序的区间.
最后输入一个整数,表示排序完之后询问的位置.
Output
输出数据仅有一行一个整数,表示按照顺序将全部的部分排序结束后第位置上的数字.
Sample Input
6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3
Sample Output
5
HINT
Solution
二分答案.
把的位置标为,其余标为.
线段树维护排序操作,最后判断位置上是否为.
#include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define N 100005 #define M 300005 using namespace std; struct linetree{ int l,r,t,op; }lt[M]; struct quest{ int op,l,r; }b[N]; int a[N],n,m,q,t,l,r,mid; inline void build(int u,int l,int r,int k){ lt[u].l=l;lt[u].r=r;lt[u].op=0; if(lt[u].l<lt[u].r){ int lef=u<<1,rig=u<<1|1; int mid=(lt[u].l+lt[u].r)>>1; build(lef,l,mid,k);build(rig,mid+1,r,k); lt[u].t=lt[lef].t+lt[rig].t; } else if(a[lt[u].l]>=k) lt[u].t=0; else lt[u].t=1; } inline void cover(int u,int i){ if(lt[u].l>=b[i].l&<[u].r<=b[i].r){ if(!b[i].op){ lt[u].op=-1; if(lt[u].l-b[i].l+1<=t){ lt[u].t=min(t-(lt[u].l-b[i].l),lt[u].r-lt[u].l+1); } else lt[u].t=0; } else{ lt[u].op=1; if(b[i].r-lt[u].r+1<=t){ lt[u].t=min(t-(b[i].r-lt[u].r),lt[u].r-lt[u].l+1); } else lt[u].t=0; } } else if(lt[u].l<lt[u].r){ int lef=u<<1,rig=u<<1|1; int mid=(lt[u].l+lt[u].r)>>1; if(lt[u].op>0)/*降序*/{ lt[u].op=0;lt[lef].op=lt[rig].op=1; lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1); lt[lef].t=lt[u].t-lt[rig].t; } else if(lt[u].op<0)/*升序*/{ lt[u].op=0;lt[lef].op=lt[rig].op=-1; lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1); lt[rig].t=lt[u].t-lt[lef].t; } if(b[i].l<=mid) cover(lef,i); if(b[i].r>mid) cover(rig,i); lt[u].t=lt[lef].t+lt[rig].t; } } inline int ask(int u,int l,int r){ if(lt[u].l>=l&<[u].r<=r) return lt[u].t; if(lt[u].l<lt[u].r){ int lef=u<<1,rig=u<<1|1,ret=0; int mid=(lt[u].l+lt[u].r)>>1; if(lt[u].op>0)/*降序*/{ lt[u].op=0;lt[lef].op=lt[rig].op=1; lt[rig].t=min(lt[u].t,lt[rig].r-lt[rig].l+1); lt[lef].t=lt[u].t-lt[rig].t; } else if(lt[u].op<0)/*升序*/{ lt[u].op=0;lt[lef].op=lt[rig].op=-1; lt[lef].t=min(lt[u].t,lt[lef].r-lt[lef].l+1); lt[rig].t=lt[u].t-lt[lef].t; } if(l<=mid) ret+=ask(lef,l,r); if(r>mid) ret+=ask(rig,l,r); return ret; } } inline bool chk(int k){ build(1,1,n,k); for(int i=1;i<=m;++i){ t=ask(1,b[i].l,b[i].r);cover(1,i); } return !ask(1,q,q); } inline void init(){ 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",&b[i].op,&b[i].l,&b[i].r); scanf("%d",&q); l=1;r=n; while(l<r){ mid=(l+r+1)>>1; if(chk(mid)) l=mid; else r=mid-1; } printf("%d\n",l); } int main(){ freopen("sort.in","r",stdin); freopen("sort.out","w",stdout); init(); fclose(stdin); fclose(stdout); return 0; }
时间: 2024-10-10 09:01:19