bzoj4552
二分在q位置上的数。其他数若大于它,则为1,否则为0,最后若该位上的数为0,则区间右移l,否则左移r
check过程中用线段树维护,降序升序可以用区间复制实现
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; const int N=100005; int n,m,q,tr[4*N],laz[4*N],a[N],typ[N],ql[N],qr[N],val[N]; inline int read(){ char ch=getchar();int k=0,f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-'0';ch=getchar();} return k*f; } void buildtr(int now,int l,int r){ laz[now]=0; if(l==r){tr[now]=val[l];return;} int mid=(l+r)>>1; buildtr(now<<1,l,mid);buildtr(now<<1|1,mid+1,r); tr[now]=tr[now<<1]+tr[now<<1|1]; } void pushdown(int now,int l,int r){ if(laz[now]==0)return; int mid=(l+r)>>1; if(laz[now]==1){ laz[now<<1]=laz[now<<1|1]=1;laz[now]=0; tr[now<<1]=mid-l+1;tr[now<<1|1]=r-mid; }else if(laz[now]==-1){ laz[now<<1]=laz[now<<1|1]=-1;laz[now]=0; tr[now<<1]=tr[now<<1|1]=0; } } void change(int now,int l,int r,int L,int R,int v){ if(l>=L&&r<=R){ if(v==1){laz[now]=1;tr[now]=r-l+1;}else{laz[now]=-1;tr[now]=0;} return; } pushdown(now,l,r); int mid=(l+r)>>1; if(mid>=L)change(now<<1,l,mid,L,R,v); if(mid<R)change(now<<1|1,mid+1,r,L,R,v); tr[now]=tr[now<<1]+tr[now<<1|1]; } int query(int now,int l,int r,int L,int R){ if(l>=L&&r<=R)return tr[now]; pushdown(now,l,r); int mid=(l+r)>>1,res=0; if(mid>=L)res+=query(now<<1,l,mid,L,R); if(mid<R)res+=query(now<<1|1,mid+1,r,L,R); return res; } void Putans(int x){ if(x>=10)Putans(x/10);putchar(x%10+'0'); } int main(){ n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=1;i<=m;i++){typ[i]=read();ql[i]=read();qr[i]=read();if(ql[i]>qr[i])swap(ql[i],qr[i]);} q=read(); int l=1,r=n; while(l<r){ int mid=(l+r)>>1; for(int i=1;i<=n;i++)val[i]=a[i]>mid?1:0; buildtr(1,1,n); for(int i=1;i<=m;i++){ int cnt=query(1,1,n,ql[i],qr[i]); if(typ[i]==0){ if(cnt>0&&cnt<qr[i]-ql[i]+1)change(1,1,n,qr[i]-cnt+1,qr[i],1); if(qr[i]-cnt>=ql[i]&&cnt>0)change(1,1,n,ql[i],qr[i]-cnt,0); } else{ if(cnt>0&&cnt<qr[i]-ql[i]+1)change(1,1,n,ql[i],ql[i]+cnt-1,1); if(ql[i]+cnt<=qr[i]&&cnt>0)change(1,1,n,ql[i]+cnt,qr[i],0); } } if(query(1,1,n,q,q))l=mid+1;else r=mid; } Putans(l); }