[bzoj4552][Tjoi2016&Heoi2016]排序
这道题刚看的时候感觉不可做.
但是最后的询问只有一个这个限制很有用.
我们可以二分最后询问的答案,然后将序列转化为01序列,01序列的排序是可以用01的区间覆盖做的.
然后这道题就被解决了.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<iomanip> #include<algorithm> #include<map> using namespace std; #define LL long long #define FILE "dealing" #define up(i,j,n) for(int i=j;i<=n;++i) #define db double #define ull unsigned long long #define eps 1e-10 #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f*x; } const int maxn=400200,mod=(int)(1e9+7+0.1),limit=(int)(1e6+1); int n,m; int a[maxn]; int val[maxn],flag[maxn],f[maxn],siz[maxn]; int op[maxn],le[maxn],ri[maxn],q; bool b[maxn]; void updata(int x){ siz[x]=siz[x<<1]+siz[x<<1|1]; } void fugai(int x,int d,int l,int r){ flag[x]=1; f[x]=d; siz[x]=(r-l+1)*d; } void pushdown(int x,int l,int r){ if(flag[x]){ flag[x]=0; int mid=(l+r)>>1; fugai(x<<1,f[x],l,mid); fugai(x<<1|1,f[x],mid+1,r); f[x]=0; } } int L,R,key; void change(int x,int l,int r){ if(l>R||r<L)return; if(l>=L&&r<=R){ fugai(x,key,l,r); return; } int mid=(l+r)>>1; pushdown(x,l,r); change(x<<1,l,mid); change(x<<1|1,mid+1,r); updata(x); } void Change(int l,int r,int K){ L=l,R=r,key=K; change(1,1,n); } void build(int x,int l,int r){ if(l==r){ siz[x]=b[l]?1:0; flag[x]=f[x]=0; return; } int mid=(l+r)>>1; pushdown(x,l,r); build(x<<1,l,mid); build(x<<1|1,mid+1,r); updata(x); } int query(int x,int l,int r){ if(l>R||r<L)return 0; if(l>=L&&r<=R)return siz[x]; int mid=(l+r)>>1; pushdown(x,l,r); return query(x<<1,l,mid)+query(x<<1|1,mid+1,r); } int Query(int l,int r){L=l,R=r;return query(1,1,n);} bool check(int mid){ for(int i=1;i<=n;i++){ if(a[i]<=mid)b[i]=0; else b[i]=1; } build(1,1,n); for(int i=1;i<=m;i++){ if(op[i]==0){ int sum=ri[i]-le[i]+1,rcnt=Query(le[i],ri[i]),lcnt=sum-rcnt; Change(le[i],le[i]+lcnt-1,0); Change(ri[i]-rcnt+1,ri[i],1); } else { int sum=ri[i]-le[i]+1,rcnt=Query(le[i],ri[i]),lcnt=sum-rcnt; Change(le[i],le[i]+rcnt-1,1); Change(ri[i]-lcnt+1,ri[i],0); } } int sum=Query(q,q); if(sum==1)return 0; else return 1; } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,1,n)a[i]=read(); up(i,1,m){ op[i]=read(); le[i]=read(),ri[i]=read(); } q=read(); int left=1,right=n,ans=0; while(left<=right){ int mid=(left+right)>>1; if(!check(mid))left=mid+1; else right=mid-1,ans=mid; } cout<<ans<<endl; return 0; }