POJ 2528 Mayor's posters(离散化 + 线段树)

题意:

那个城市里要竞选市长,然后在一块墙上可以贴海报为自己拉票,每个人可以贴连续的一块区域,后来帖的可以覆盖前面的,问到最后一共可以看到多少张海报。

分析:

线段树的区间更新。每贴一张海报就是把一个连续的区间的值全部更改,但这里的数据比较大,直接做可能时间空间复杂度都很高。
因为最多只有10000张海报,而即使每张海报的两个端点都不相同,最多就有20000个有用的端点,所以可以采用把这些位置去重,每次二分查找左区间和右区间的位置,然后把左区间和右区间的位置进行线段树的区间更新,查询的时候就用一个vis数组进行标记如果没有用过的标记ans++,用过的直接return。

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <map>
#define ls 2*o
#define rs 2*o+1
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 2e4 + 10;
int setv[N<<2];
bool vis[N*2];
struct Item {
    int L, R;
} item[N];
int x[N], ans;

void build(int o, int L, int R) {
    setv[o] = 0;
    if(L == R) return;
    int M = (L+R)/2;
    build(ls, L, M);
    build(rs, M+1, R);
}

void pushdown(int o) {
    if(setv[o]) {
        setv[ls] = setv[rs] = setv[o];
        setv[o] = 0;
    }
}

void maintain(int o) {
    if(setv[ls] == setv[rs]) setv[o] = setv[ls];
}

int ql, qr, val;
void modify(int o, int L, int R) {
    if(ql <= L && R <= qr) {
        setv[o] = val;
        return ;
    }
    pushdown(o);
    int M = (L+R)/2;
    if(ql <= M) modify(ls, L, M);
    if(qr > M) modify(rs, M+1, R);
    maintain(o);
}

void query(int o, int L, int R) {
    if(setv[o]) {
        if(!vis[setv[o]]) {
            ans++;
            vis[setv[o]] = true;
            return;
        }
        else return ;
    }
    if(L == R) return ;
    int M = (L+R)/2;
    query(ls, L, M);
    query(rs, M+1, R);
}

int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    int n, m;
    scanf("%d", &T);
    while(T--) {
        //init
        memset(vis, false, sizeof(vis));
        scanf("%d", &m);
        n = 0;
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &item[i].L, &item[i].R);
            x[n++] = item[i].L;
            x[n++] = item[i].R;
        }
        //排序去重复并离散化
        sort(x, x+n);
        n = unique(x, x+n) - x;

        //构建线段树
        build(1, 1, n);
        for(int i = 0; i < m; i++) {
            ql = lower_bound(x, x+n, item[i].L) - x+1;
            qr = lower_bound(x, x+n, item[i].R) - x+1;
            val = i+1;
            modify(1, 1, n);
        }
        ans = 0;
        query(1, 1, n);
        printf("%d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(poj,2528)