"HEOI2016 / TJOI2016" Sort

Topic Link

I poke

\(Solution\)

This question is not the practice of online, offline so here they talk about the practice.

Because direct sequencing, then the complexity is obviously wrong. But if the number listed as \ (01 \) string, then you can make a right turn into the complexity of the

So \ (01 \) string how to do it?

We consider maintaining this thing with the tree line.

Suppose we want to \ ([l, r] \ ) Sort

We can handle the \ ([l, r] \ ) in \ (1 \) number, we let him \ (W \)

If the ASC will \ ([r-x + 1 , r] \) is set to 1, the balance being \ (0 \)

If the descending order will be \ ([l, l + x -1] \) is set to 1, the balance being \ (0 \)

So the question becomes how the above situation?

We dichotomy final answer, so this number is \ (MID \) .

For the sequence number is less than \ (MID \) to as \ (0 \) , greater than \ (MID \) to as \ (1 \)

Root is then operated as the above-described process.

The last judgment \ (Q \) position is the \ (1 \)

Is, \ (L = MID. 1 + \)

否,\(r=mid-1\)

Now to prove what this monotonic.

If \ (q \) the number of this position is \ (1 \) , then the answer is affirmative \ (x + 1, x + 2, x + 3 ... \) so the interval to the right, and vice versa.

\(Code\)

#include<bits/stdc++.h>
#define rg register
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
    return f*x;
}
struct node {
    int lazy,v;
}a[1000001];
int c[1000001];
void pushup(int k){
    a[k].v=a[k<<1].v+a[k<<1|1].v;
}
void build(int k,int l,int r){
    a[k].lazy=-1,a[k].v=0;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
void pushdown(int k,int l,int r){
    if(a[k].lazy==-1) return;
    int mid=(l+r)>>1;
    a[k<<1].v=(mid-l+1)*a[k].lazy;
    a[k<<1|1].v=(r-mid)*a[k].lazy;
    a[k<<1].lazy=a[k<<1|1].lazy=a[k].lazy;
    a[k].lazy=-1;
}
void update(int k,int l,int r,int begin,int end,int v){
    if(r<begin||l>end) return ;
    if(r<=end&&l>=begin){
        a[k].v=(r-l+1)*v;
        a[k].lazy=v;
        return ;
    }
    pushdown(k,l,r);
    int mid=(l+r)>>1;
    update(k<<1,l,mid,begin,end,v);
    update(k<<1|1,mid+1,r,begin,end,v);
    pushup(k);
}
int find(int k,int l,int r,int begin,int end){
    if(r<begin&&l>end) return 0;
    if(r<=end&&l>=begin) return a[k].v;
    pushdown(k,l,r);
    int mid=(l+r)>>1;
    if(end<=mid)
        return find(k<<1,l,mid,begin,end);
    else if(begin>mid)
        return find(k<<1|1,mid+1,r,begin,end);
    else return find(k<<1,l,mid,begin,mid)+find(k<<1|1,mid+1,r,mid+1,end);
}
struct ans{
    int opt,x,y;
}b[1000001];
int n,m,ans,l,r,q;
bool check(int x){
    build(1,1,n);
    for(int i=1;i<=n;i++)
        update(1,1,n,i,i,c[i]>=x);
    for(int i=1;i<=m;i++){
        int opt=b[i].opt,x=b[i].x,y=b[i].y;
        int w1=find(1,1,n,x,y),w0=y-x+1-w1;
        if(opt==0)
            update(1,1,n,x,y,1),update(1,1,n,x,x+w0-1,0);
        else update(1,1,n,x,y,0),update(1,1,n,x,x+w1-1,1);
    }
    return find(1,1,n,q,q)==1;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++) c[i]=read();
    for(int i=1;i<=m;i++) b[i].opt=read(),b[i].x=read(),b[i].y=read();
    l=1,r=n,q=read();
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) l=mid+1,ans=mid;
        else r=mid-1;
    }
    printf("%d",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hbxblog/p/11708862.html