1232 - SKYLINE

算法竞赛训练指南P247

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>

#define INF 0x3fffffff
#define N 100010
#define M (100010 << 2)
#define LL long long
#define mod 95041567

using namespace std;

struct Node{
    int set, MAX;
};

Node p[M];
int cnt;
int arr[N][3];

void build(int rt, int l, int r){
    if(l == r){
        p[rt].set = p[rt].MAX = 0;
        return;
    }
    int mid = (r - l) / 2 + l;
    int lc = rt << 1;
    int rc = lc + 1;
    build(lc, l, mid);
    build(rc, mid + 1, r);
    p[rt].set = p[rt].MAX = 0;
}

void maintain(int rt){
    if(! p[rt].set) return;
    int lc = rt << 1;
    int rc = lc + 1;
    p[lc] = p[rt];
    p[rc] = p[rt];
    p[rt].set = 0;
}

void dfs(int rt, int l, int r, int val){
    if(p[rt].MAX <= val){
        p[rt].MAX = val;
        p[rt].set = val;
        cnt += r - l + 1;
        // printf("%d %d %d\n", l, r, p[rt].MAX);
        // printf("%d\n", cnt);
        return;
    }
    if(r <= l) return;
    if(p[rt].set > val) return;
    maintain(rt);
    int mid = (r - l) / 2 + l;
    int lc = rt << 1;
    int rc = lc + 1;
    dfs(lc, l, mid, val);
    dfs(rc, mid + 1, r, val);
    p[rt].MAX = max(p[lc].MAX, p[rc].MAX);
}

void update(int rt, int l, int r, int L, int R, int val){
    int mid = (r - l) / 2 + l;
    int lc = rt << 1;
    int rc = lc + 1;
    if(l == L && r == R){
        dfs(rt, l, r, val);
        return;
    }
    if(p[rt].set > val) return;
    maintain(rt);
    if(L > mid) update(rc, mid + 1, r, L, R, val);
    else if(R <= mid) update(lc, l, mid, L, R, val);
    else {
        update(lc, l, mid, L, mid, val);
        update(rc, mid + 1, r, mid + 1, R, val);
    }
    p[rt].MAX = max(p[lc].MAX, p[rc].MAX);
}

int main() {
 //   freopen("in.txt","r",stdin);
    int t;
    while(scanf("%d", &t) != EOF){
        if(! t) break;
        while(t --){
            int n, right = 0, left = INF;
            scanf("%d", &n);
            for(int i = 0; i < n; ++ i){
                scanf("%d %d %d", &arr[i][0], &arr[i][1], &arr[i][2]);
                left = min(left, arr[i][0]);
                right = max(right, arr[i][1]);
            }
            -- right;
            cnt = 0;
            build(1, left, right);
            for(int i = 0; i < n; ++ i)
                update(1, left, right, arr[i][0], arr[i][1] - 1, arr[i][2]);
            printf("%d\n", cnt);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moyan_min/article/details/12920531
今日推荐