在2016年,佳媛姐姐喜欢上了数字序列。因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题
,需要你来帮助他。这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排
序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q
位置上的数字。
输出数据仅有一行,一个整数,表示按照顺序将全部的部分排序结束后第q位置上的数字。
二分答案+线段树,思路好
二分一个答案,大于它的全部视为1,小于它的全部视为-1,然后在线段树上乱搞。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define N 100005 using namespace std; int n,m,q,now; int a[N],tag[N*4],sum[N*4]; struct data{int op,l,r;}p[N]; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void pushup(int k) { sum[k]=sum[k<<1]+sum[k<<1|1]; } void update(int k,int l,int r,int x) { tag[k]=x; sum[k]=(r-l+1)*x; } void pushdown(int k,int l,int r) { if (!tag[k]) return; int mid=(l+r)>>1; update(k<<1,l,mid,tag[k]);update(k<<1|1,mid+1,r,tag[k]); tag[k]=0; } void build(int k,int l,int r) { tag[k]=0; if (l==r) { sum[k]=a[l]==now?0:(a[l]<now?-1:1); return; } int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); pushup(k); } void change(int k,int l,int r,int L,int R,int x) { if (L>R) return; if (l==L&&r==R){update(k,l,r,x);return;} pushdown(k,l,r); int mid=(l+r)>>1; if (R<=mid) change(k<<1,l,mid,L,R,x); else if (L>mid) change(k<<1|1,mid+1,r,L,R,x); else change(k<<1,l,mid,L,mid,x),change(k<<1|1,mid+1,r,mid+1,R,x); pushup(k); } int query(int k,int l,int r,int L,int R) { if (l==L&&r==R) return sum[k]; pushdown(k,l,r); int mid=(l+r)>>1; if (R<=mid) return query(k<<1,l,mid,L,R); else if (L>mid) return query(k<<1|1,mid+1,r,L,R); else return query(k<<1,l,mid,L,mid)+query(k<<1|1,mid+1,r,mid+1,R); } int main() { n=read();m=read(); F(i,1,n) a[i]=read(); F(i,1,m) p[i].op=read(),p[i].l=read(),p[i].r=read(); q=read(); int l=1,r=n; while (l<=r) { now=(l+r)>>1; build(1,1,n); F(i,1,m) { int sum=query(1,1,n,p[i].l,p[i].r),num=p[i].r-p[i].l+1; if ((sum+num)%2!=0) num--; int x=(num+sum)>>1,y=(num-sum)>>1; if (p[i].op) { change(1,1,n,p[i].l,p[i].l+x-1,1); change(1,1,n,p[i].l+x,p[i].r-y,0); change(1,1,n,p[i].r-y+1,p[i].r,-1); } else { change(1,1,n,p[i].l,p[i].l+y-1,-1); change(1,1,n,p[i].l+y,p[i].r-x,0); change(1,1,n,p[i].r-x+1,p[i].r,1); } } int tmp=query(1,1,n,q,q); if (tmp==0){printf("%d\n",now);return 0;} if (tmp<0) r=now-1;else l=now+1; } return 0; }