[HEOI2016/TJOI2016]排序(01线段树)

洛谷

大于等于中间数为一

小于为0

二分查找

#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=1e5+5;
#define ls rt<<1
#define rs rt<<1|1

int n,m,a[maxn],k;

bool tr[maxn<<2];
int lazy[maxn<<2];
int sum[maxn<<2];

struct node{
    int l,r,type;
}que[maxn];

inline void build(int rt,int l,int r,int x)
{
    lazy[rt]=0;
    if(l==r)
    {
        sum[rt]=tr[rt]=(a[l]>=x);
        re ;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid,x);
    build(rs,mid+1,r,x);
    
    sum[rt]=sum[ls]+sum[rs];
}

inline void pushdown(int rt,int l,int r,int mid)
{
    lazy[ls]=lazy[rs]=lazy[rt];
    if(lazy[rt]==1)
    {
        sum[ls]=mid-l+1;
        sum[rs]=r-mid;
        tr[ls]=tr[rs]=1;
    }
    else
    {
        sum[ls]=sum[rs]=0;
        tr[ls]=tr[rs]=0;
    }
    lazy[rt]=0;
}

inline void modify(int rt,int l,int r,int x,int y,int col)
{
    if(x<=l&&r<=y)
    {
        lazy[rt]=(col==1?1:2);
        tr[rt]=col;
        if(col)sum[rt]=r-l+1;
        else sum[rt]=0;
        re ;
    }
    int mid=(l+r)>>1;
    if(lazy[rt])pushdown(rt,l,r,mid);
    if(x<=mid)modify(ls,l,mid,x,y,col);
    if( y>mid)modify(rs,mid+1,r,x,y,col);
    sum[rt]=sum[ls]+sum[rs]; 
}

inline int G_sum(int rt,int l,int r,int x,int y)
{
    if(x<=l&&r<=y)re sum[rt];
    int mid=(l+r)>>1;
    if(lazy[rt])pushdown(rt,l,r,mid);
    if(x>mid)re G_sum(rs,mid+1,r,x,y);
    else if(y<=mid)re G_sum(ls,l,mid,x,y);
    re G_sum(ls,l,mid,x,y)+G_sum(rs,mid+1,r,x,y);
}

inline bool query(int rt,int l,int r,int pos)
{
    if(l==r)
        re tr[rt];
    int mid=(l+r)>>1;
    if(lazy[rt])pushdown(rt,l,r,mid);
    if(pos<=mid)re query(ls,l,mid,pos);
    re query(rs,mid+1,r,pos);
}

inline bool check(int x)
{
    build(1,1,n,x);
    
    inc(i,1,m)
    {
        int S=G_sum(1,1,n,que[i].l,que[i].r);
        if(que[i].type)
        {
            if(que[i].l+S-1>=que[i].l)modify(1,1,n,que[i].l,que[i].l+S-1,1);
            modify(1,1,n,que[i].l+S,que[i].r,0);
        }
        else
        {
            modify(1,1,n,que[i].l,que[i].r-S,0);
            if(que[i].r-S+1<=que[i].r)modify(1,1,n,que[i].r-S+1,que[i].r,1);
        }
/*    if(x==6)
    {
        inc(i,1,6)
    printf("%d ",query(1,1,n,i));
    printf("\n");
    }*/
    }
    re query(1,1,n,k);
}

int main()
{
    freopen("in.txt","r",stdin);
    rd(n),rd(m);
    inc(i,1,n)rd(a[i]);
    inc(i,1,m)
    {
        rd(que[i].type);
        rd(que[i].l);
        rd(que[i].r);
    }
    
    rd(k);
    int l=1,r=n;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid))l=mid+1;
        else r=mid-1; 
    }
    
    printf("%d",r);
    re 0;
} 
View Code

 

posted @ 2019-10-08 22:02  凉如水  阅读(196)  评论(0编辑  收藏  举报