线段树+离散化问题

来源:互联网 发布:张丕林 知乎 编辑:程序博客网 时间:2024/06/05 03:23

线段树+离散化的问题。


Mayor’s posters

题目传送:POJ - 2528 - Mayor’s posters

参考胡浩的写法。

AC代码:

#include <map>#include <set>#include <list>#include <cmath>#include <deque>#include <queue>#include <stack>#include <bitset>#include <cctype>#include <cstdio>#include <string>#include <vector>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <sstream>#include <utility>#include <iostream>#include <algorithm>#include <functional>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 12345;bool Hash[maxn];int li[maxn], ri[maxn];//记录输入海报的左右位置int X[maxn * 3], cx;//记录输入的所有位置以及对应位置个数int col[maxn << 4];//用颜色标记海报,-1表示该区间有多种海报(颜色)int ans;int n;int b_search(int key, int n, int X[]) {//二分查找    int l = 0, r = n - 1;    while(l <= r) {        int m = (l + r) >> 1;        if(X[m] == key) return m;        if(X[m] < key) l = m + 1;        else r = m - 1;    }    return -1;}void pushdown(int rt) {    if(col[rt] != -1) {        col[rt << 1] = col[rt << 1 | 1] = col[rt];        col[rt] = -1;    }}void update(int rt, int l, int r, int c, int L, int R) {//插入    if(L <= l && r <= R) {        col[rt] = c;        return;    }    pushdown(rt);    int mid = (l + r) >> 1;    if(L <= mid) update(rt << 1, l, mid, c, L, R);    if(R >= mid + 1) update(rt << 1 | 1, mid + 1, r, c, L, R);}void query(int rt, int l, int r) {//查询,带hash判重    if(col[rt] != -1) {        if(!Hash[col[rt]]) {            ans ++;            Hash[col[rt]] = true;        }        return;    }    if(l == r) return;    int mid = (l + r) >> 1;    query(rt << 1, l, mid);    query(rt << 1 | 1, mid + 1, r);}int main() {    int T;    scanf("%d", &T);    while(T --) {        scanf("%d", &n);        cx = 0;         for(int i = 0; i < n; i ++) {            scanf("%d %d", &li[i], &ri[i]);            X[cx ++] = li[i];            X[cx ++] = ri[i];        }        sort(X, X + cx);        int m = 1;        for(int i = 1; i < cx; i ++) {//去重            if(X[i] != X[i - 1]) X[m ++] = X[i];        }        for(int i = m - 1; i > 0; i --) {//解决相邻数字大于1的问题,通过插入一个数字            if(X[i] != X[i - 1] + 1) X[m ++] = X[i - 1] + 1;        }        sort(X, X + m);        memset(col, -1, sizeof(col));        for(int i = 0; i < n; i ++) {            int l = b_search(li[i], m, X);//二分查找离散化之后对应的那个值            int r = b_search(ri[i], m, X);            update(1, 0, m, i, l, r);        }        ans = 0;        memset(Hash, 0, sizeof(Hash));        query(1, 0, m);        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击