hdoj 3627 Giant For

類型:線段樹

題目:http://acm.hdu.edu.cn/showproblem.php?pid=3627

來源:2010 Asia Regional Tianjin Site —— Online Contest

思路:將讀入的數據排序後離散化,以下標爲葉子節點建立線段樹,葉子節點存儲該位置處的列值,非葉子節點存儲該區間中葉子的最大列值。然後進行線段樹的插入、刪除和查找【給定查找區間】

!!!find_i函數位置的確定

!!!查詢時的比較

// hdoj 3627 Giant For
// wa ce wa re ac 1609MS 12732K
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(i = (a); i > (b); --i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)
#define max(a,b) ((a) > (b)) ? (a) : (b)
#define min(a,b) ((a) < (b)) ? (a) : (b)
#define CLR(a,b) memset(a,b,sizeof(a))
#define PB(x) push_back(x)

const int MAXN = 200010;
const int MAXM = 0;
const int hash_size = 25000002;
const int INF = 0x7f7f7f7f;

int n, cnt, cas = 1;
char ch[MAXN][10];
struct node {
    int l, r;
    int max_cal;
}seg_tree[MAXN * 4];
struct data {
    int x, y;
}num[MAXN], st[MAXN], endd[MAXN];

int find_i(int x, int y) {
    int l = 1, r = cnt, mid;
    while(l <= r) {
        mid = (l + r) >> 1;
        //!!!
        if(endd[mid].x > x)
            r = mid - 1;
        else
            l = mid + 1;
    }
    while(--l) {
        if(endd[l].y == y)
            return l;
    }
}

void build(int l, int r, int num) {
    seg_tree[num].l = l;
    seg_tree[num].r = r;
    seg_tree[num].max_cal = 0;
    int mid = (l + r) >> 1;
    if(r > l) {
        build(l, mid, num << 1);
        build(mid + 1, r, (num << 1) | 1);
    }
}

void insert(int i, int num) {
    if(seg_tree[num].l == seg_tree[num].r) {
        seg_tree[num].max_cal = endd[i].y;
        return ;
    }
    int mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
    if(i <= mid)
        insert(i, num << 1);
    else
        insert(i, (num << 1) | 1);
    seg_tree[num].max_cal = max(seg_tree[num << 1].max_cal, seg_tree[(num << 1) | 1].max_cal);
}

void dele(int i, int num) {
    if(seg_tree[num].l == seg_tree[num].r) {
        seg_tree[num].max_cal = 0;
        return ;
    }
    int mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
    if(i <= mid)
        dele(i, num << 1);
    else
        dele(i, (num << 1) | 1);
}

int query(int i, int num, int l, int r) {
    if(seg_tree[num].max_cal <= endd[i].y)
        return -1;
    if(seg_tree[num].l == seg_tree[num].r) {
        //!!!
        if(endd[seg_tree[num].l].x > endd[i].x && seg_tree[num].max_cal > endd[i].y)
            return seg_tree[num].l;
        return -1;
    }
    int ans = -1, mid = (seg_tree[num].l + seg_tree[num].r) >> 1;
    if(l <= mid)
        ans = query(i, num << 1, l, r);
    if(r > mid && ans == -1)
        ans = query(i, (num << 1) | 1, l, r);
    return ans;
}

bool cmp(data a, data b) {
    if(a.x != b.x)
        return a.x < b.x;
    return a.y < b.y;
}

void solve() {
    int i;

    sort(st + 1, st + 1 + n, cmp);
    endd[1].x = st[1].x, endd[1].y = st[1].y;
    cnt = 1;
    FORE(i, 2, n) {
        if(st[i].x == st[i - 1].x && st[i].y == st[i - 1].y)
            continue;
        else
            endd[++cnt] = st[i];
    }
    endd[++cnt].x = INF,  endd[cnt].y = INF;
    build(1, cnt + 1, 1);
    if(cas > 1)
        printf("\n");
    printf("Case %d:\n", cas++);
    FORE(i, 1, n) {
        int t = find_i(num[i].x, num[i].y);
        if(!strcmp(ch[i], "add"))
            insert(t, 1);
        if(!strcmp(ch[i], "remove"))
            dele(t, 1);
        if(!strcmp(ch[i], "find")) {
            int tmp = query(t, 1, t, cnt);
            if(tmp == -1)
                printf("-1\n");
            else
                printf("%d %d\n", endd[tmp].x, endd[tmp].y);
        }
    }
}

void init() {
    int i;

    FORE(i, 1, n) {
        scanf("%s %d %d", ch[i], &num[i].x, &num[i].y);
        st[i].x = num[i].x, st[i].y = num[i].y;
    }
}

int main() {
    while(scanf("%d", &n) == 1, n) {
        init();
        solve();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章