loj2055 "TJOI / HEOI2016" sort

ref

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, m, a[100005], sum[400005], tag[400005], q;
struct Node{
    int opt, lll, rrr;
}nd[100005];
void pushDown(int o, int l, int r, int lson, int rson, int mid){
    tag[lson] = tag[rson] = tag[o];
    sum[lson] = (mid - l + 1) * tag[o];
    sum[rson] = (r - mid) * tag[o];
    tag[o] = -1;
}
void modify(int o, int l, int r, int x, int y, int k){
    if(x>y) return ;
    if(l>=x && r<=y){
        sum[o] = (r - l + 1) * k;
        tag[o] = k;
    }
    else{
        int mid=(l+r)>>1;
        int lson=o<<1;
        int rson=lson|1;
        if(tag[o]!=-1)  pushDown(o, l, r, lson, rson, mid);
        if(x<=mid)  modify(lson, l, mid, x, y, k);
        if(mid<y)   modify(rson, mid+1, r, x, y, k);
        sum[o] = sum[lson] + sum[rson];
    }
}
int query(int o, int l, int r, int x, int y){
    if(x>y) return 0;
    if(l>=x && r<=y)    return sum[o];
    else{
        int mid=(l+r)>>1;
        int lson=o<<1;
        int rson=lson|1;
        if(tag[o]!=-1)  pushDown(o, l, r, lson, rson, mid);
        int re=0;
        if(x<=mid)  re += query(lson, l, mid, x, y);
        if(mid<y)   re += query(rson, mid+1, r, x, y);
        return re;
    }
}
bool chk(int lim){
    memset(sum, 0, sizeof(sum));
    memset(tag, -1, sizeof(tag));
    for(int i=1; i<=n; i++)
        if(a[i]>lim)
            modify(1, 1, n, i, i, 1);
    for(int i=1; i<=m; i++){
        int x=query(1, 1, n, nd[i].lll, nd[i].rrr);
        if(nd[i].opt){
            modify(1, 1, n, nd[i].lll, nd[i].lll+x-1, 1);
            modify(1, 1, n, nd[i].lll+x, nd[i].rrr, 0);
        }
        else{
            x = nd[i].rrr - nd[i].lll + 1 - x;
            modify(1, 1, n, nd[i].lll, nd[i].lll+x-1, 0);
            modify(1, 1, n, nd[i].lll+x, nd[i].rrr, 1);
        }

    }
    return query(1, 1, n, q, q)==0;
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        scanf("%d", &a[i]);
    for(int i=1; i<=m; i++)
        scanf("%d %d %d", &nd[i].opt, &nd[i].lll, &nd[i].rrr);
    cin>>q;
    int l=1, r=n, mid, re;
    while(l<=r){
        mid = (l + r) >> 1;
        if(chk(mid))    re = mid, r = mid - 1;
        else    l = mid + 1;
    }
    cout<<re<<endl;
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325223049&siteId=291194637