# bzoj 4552 洛谷P2824: [Tjoi2016&Heoi2016]排序

## ODT&二分

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<set>
#define IT set<node>::iterator
using namespace std;
int n,m,opt,k,ll,rr,ans;
int a[100010];
int l[100010],r[100010];
int pan[100010];

int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
return s*w;
}

struct node
{
int l,r;
mutable int val;
node(int L,int R=-1,int V=0):l(L),r(R),val(V){}
friend bool operator <(const node &a,const node &b)
{
return a.l<b.l;
}
};

set<node>s;

IT split(int pos)
{
IT it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos)return it;
--it;
int L=it->l,R=it->r;
int V=it->val;
s.erase(it);
s.insert(node{L,pos-1,V});
return s.insert(node{pos,R,V}).first;
}

int sum(int l,int r)
{
IT it2=split(r+1),it1=split(l);
int res=0;
for(;it1!=it2;++it1)
if(it1->val)res+=(it1->r-it1->l+1);
return res;
}

void tuiping(int l,int r,int v)
{
IT it2=split(r+1),it1=split(l);
s.erase(it1,it2);
s.insert(node{l,r,v});
}

int check(int x)
{
s.clear();
int val=(a[1]>=x),len=1;
for(int i=2;i<=n;++i)
{
if((a[i]>=x)!=val)
{
s.insert(node{i-len,i-1,val});
val=(a[i]>=x);len=1;
}
else len++;
}
s.insert(node{n-len+1,n,val});
s.insert(node{n+1,n+1,1});
for(int i=1;i<=m;++i)
{
if(pan[i]==0)//升序
{
int lin=r[i]-l[i]+1-sum(l[i],r[i]);//cout<<"lin="<<lin<<endl;
tuiping(l[i],l[i]+lin-1,0);
tuiping(l[i]+lin,r[i],1);
}
else
{
int lin=sum(l[i],r[i]);
tuiping(l[i],l[i]+lin-1,1);
tuiping(l[i]+lin,r[i],0);
}
}
return sum(k,k);
}

void slove2()
{
for(int i=1;i<=m;++i)pan[i]=(bool)read(),l[i]=read(),r[i]=read();
cin>>k;
int ans=0;
ll=1;rr=n;//cout<<check(5)<<endl;;
while(ll<=rr)
{
int mid=(ll+rr)>>1;
if(check(mid))
{
ll=mid+1;
ans=mid;
}
else rr=mid-1;
}
cout<<ans;
}

int main()
{
//freopen("seq.in","r",stdin);
//freopen("seq.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;++i)a[i]=read();
slove2();
fclose(stdin);fclose(stdout);
return 0;
}

posted @ 2019-09-20 21:22  wljss  阅读(106)  评论(1编辑  收藏  举报