Submission #711511

#TimeUsernameProblemLanguageResultExecution timeMemory
711511PherokungWall (IOI14_wall)C++14
100 / 100
1354 ms232380 KiB

#include "wall.h"
#include<bits/stdc++.h>
#define MAXK 500005
#define F first
#define S second
#define INF 1000000007
using namespace std;
typedef pair<int,int> pa;
int n,k,op[MAXK],l[MAXK],r[MAXK],hi[MAXK];
pa v;
struct node{
    int val;
    pa lazy;
    node *l, *r;
};
node top;

void build(node *pos,int be,int ed){
    if(be == ed){
        pos->val = 0;
        pos->lazy = {-1,-2};
        return;
    }
    pos->l = new node, pos->r = new node;
    int mid = (be+ed) / 2;
    build(pos->l,be,mid), build(pos->r,mid+1,ed);
    pos->lazy = {-1,-2};
}

int h(int a){
    if(a == -1) return -INF;
    if(a == -2) return INF;
    if(a == 0) return 0;
    return hi[a];
}

pa merge(pa A,pa B){ // A = OLD, B = NEW
    pa C;
    C.F = (h(A.F) > h(B.F)) ? A.F : B.F;
    C.S = (h(A.S) < h(B.S)) ? A.S : B.S;
    if(h(C.F) > h(C.S)){
        if(C.F > C.S) C.S = C.F;
        else C.F = C.S;
    }
    return C;
}

void update(node *pos,int be,int ed,int x,int y,int o,int i){
    //printf("!!! %d %d \n",be,ed);
    if(pos->lazy != make_pair(-1,-2)){
        v = pos->lazy;
        pos->lazy = {-1,-2};
        if(be != ed) pos->l->lazy = merge(pos->l->lazy,v), pos->r->lazy = merge(pos->r->lazy,v);
        else{
            if(h(pos->val) < h(v.F)) pos->val = v.F;
            if(h(pos->val) > h(v.S)) pos->val = v.S;
        }
    }
    if(be > ed || ed < x || y < be) return;
    if(x <= be && ed <= y){
        v = (o == 1) ? make_pair(i,-2) : make_pair(-1,i);
        if(be != ed) pos->l->lazy = merge(pos->l->lazy,v), pos->r->lazy = merge(pos->r->lazy,v);
        else{
            if(h(pos->val) < h(v.F)) pos->val = v.F;
            if(h(pos->val) > h(v.S)) pos->val = v.S;
        }
        return;
    }
    int mid = (be+ed)/2;
    update(pos->l,be,mid,x,y,o,i), update(pos->r,mid+1,ed,x,y,o,i);
}

int query(node *pos,int be,int ed,int x){
    if(pos->lazy != make_pair(-1,-2)){
        v = pos->lazy;
        pos->lazy = {-1,-2};
        if(be != ed) pos->l->lazy = merge(pos->l->lazy,v), pos->r->lazy = merge(pos->r->lazy,v);
        else{
            if(h(pos->val) < h(v.F)) pos->val = v.F;
            if(h(pos->val) > h(v.S)) pos->val = v.S;
        }
    }
    if(be > ed || ed < x || x < be) return -1;
    if(be == ed) return pos->val;
    int mid = (be+ed)/2;
    return max(query(pos->l,be,mid,x), query(pos->r,mid+1,ed,x));
}

void buildWall(int N, int K, int OP[], int left[], int right[], int height[], int finalHeight[]){
    n = N, k = K;
    for(int i=1;i<=k;i++) op[i] = OP[i-1], l[i] = left[i-1]+1, r[i] = right[i-1]+1, hi[i] = height[i-1];
    build(&top,1,n);
    for(int i=1;i<=k;i++){
        update(&top,1,n,l[i],r[i],op[i],i);
        //for(int i=1;i<=n;i++) printf("%d ",query(&top,1,n,i));
        //printf("\n\n");
    }
    for(int i=1;i<=n;i++){
        finalHeight[i-1] = h(query(&top,1,n,i));
    }
    return;
}

/*
4 4
1 0 3 11
2 1 3 2
1 2 3 3
2 3 3 1
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...