[HEOI2016 / TJOI2016] + binary sort tree line

Title Description

In 2016, Jia Yuan sister liked the sequence of numbers. Thus he often examine some strange questions about the series, and now he studies a problem, you need to help him. This problem is like this: given a full array from 1 to n, the now full array partial sequence m times, the sort divided into two types: 1: (0, l, r) represents the interval [L, r] in ascending numerical order 2: (1, l, r) represents the interval [l, r] in descending order of the digital numbers on the last interrogation of the position q.

Input Format

Behavioral data input of the first two integers n and m. n represents the length of the sequence, m represents the number of partially ordered. 1 <= n, m <= 10 ^ 5 n integers second line, represents a full array from 1 to n. Next, the input m rows, each row has three integers op, l, r, op is 0 for ascending order, for the OP represents descending order, l, r indicates the sort range. Finally enter an integer q, q represents inquiry completion position after sorting, 1 <= q <= n. 1 <= n <= 10 ^ 5,1 <= m <= 10 ^ 5

Output Format

Output data of only one row, an integer indicating the order according to the end portions of all the first sort numbers on the position q.

Sample

Sample input

6 3
1 6 2 5 3 4
0 1 4
1 3 6
0 2 4
3

Sample Output

5

answer:

The very idea of ​​god

That question if you really go sorted died. . .

But we still have to use to segment tree

But this road and tree kruscal the same fantastic ideas

We count on the q-half position

Every half, maintaining a segment tree,

We set up the current number is assigned to x, then we let all the leaf nodes greater than or equal to x 1, x is less than 0

We have a few maintenance interval 1,

If we put before ascending order into a period of violence, after a period of change 0, descending turn,

We query q What is the position of number

If it is 1, then the current dichotomy of x may be small, but it may be the answer, use the mid updated ans, because we are to make greater than equal to the node x is 1,

If it is 0, then the current x is too large, the smaller number should be consulted

Every half of all such checks again, the end of the half ans is the answer

Anti routine questions, a lot of accumulation

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define int long long
#define MAXN 100005
using namespace std;
int n,m,a[MAXN],q,l,r,ans;
struct node{
    int opt,l,r;
}ask[MAXN];
struct Segtree{
    int l,r,val,laz;
}tree[MAXN<<2];
void down(int k){
    if(tree[k].laz==-1) return ;
    tree[k<<1].laz=tree[k].laz;
    tree[k<<1|1].laz=tree[k].laz;
    tree[k<<1].val=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].laz;
    tree[k<<1|1].val=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].laz;
    tree[k].laz=-1;
}
void build(int k,int l,int r,int x){
    tree[k].l=l,tree[k].r=r;
    tree[k].laz=-1;
    if(l==r){
        if(a[l]>=x) 
            tree[k].val=1;
        else tree[k].val=0;
        return ;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid,x);
    build(k<<1|1,mid+1,r,x);
    tree[k].val=tree[k<<1].val+tree[k<<1|1].val;
}
int query(int k,int opl,int opr){
    int l=tree[k].l,r=tree[k].r;
    if(opl<=l&&r<=opr){
        return tree[k].val;
    }
    down(k);
    int mid=(l+r)>>1;
    if(opr<=mid) return query(k<<1,opl,opr);
    if(opl>mid) return query(k<<1|1,opl,opr);
    return query(k<<1,opl,mid)+query(k<<1|1,mid+1,opr);
}
void change(int k,int opl,int opr,int val){
    int l=tree[k].l,r=tree[k].r;
    if(opl<=l&&r<=opr){
        tree[k].val=(r-l+1)*val;
        tree[k].laz=val;
        return ;
    }
    down(k);
    int mid=(l+r)>>1;
    if(opr<=mid) change(k<<1,opl,opr,val);
    else if(opl>mid) change(k<<1|1,opl,opr,val);
    else{
        change(k<<1,opl,opr,val);
        change(k<<1|1,opl,opr,val);
    }
    tree[k].val=tree[k<<1].val+tree[k<<1|1].val;
}
bool check(int x){
    build(1,1,n,x);
    for(int i=1;i<=m;i++){
        int sum=query(1,ask[i].l,ask[i].r);
        if(sum==0||sum==ask[i].r-ask[i].l+1) continue;
        if(!ask[i].opt){
            change(1,ask[i].l,ask[i].r-sum,0);
            change(1,ask[i].r-sum+1,ask[i].r,1);
        }else{
            change(1,ask[i].l,ask[i].l+sum-1,1);
            change(1,ask[i].l+sum,ask[i].r,0);
        }
    }
    return query(1,q,q);
}
signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=1;i<=m;i++){
        scanf("%lld%lld%lld",&ask[i].opt,&ask[i].l,&ask[i].r);
    }
    scanf("%lld",&q);
    l=1,r=n;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,l=mid+1;
        else r=mid-1;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Juve/p/11269638.html