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

Mayor's posters https://vjudge.net/problem/POJ-2528#author=szdytom

线段树 + 离散化

讲解:https://blog.csdn.net/qq_35802619/article/details/98326267

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define sc(n) scanf("%c",&n)
#define sd(n) scanf("%d",&n)
#define pd(n) printf("%d\n", (n))
#define sdd(n,m) scanf("%d %d",&n,&m)
#define pdd(n,m) printf("%d %d\n",n, m)
#define ms(a,b) memset(a,b,sizeof(a))
#define all(c) c.begin(),c.end()

typedef long long ll;
const int maxn = 2e5 + 5;//数组注意别开小了

struct node {
    int l, r, gg;
}tr[maxn << 2 + 5];
int lg[maxn], rg[maxn];
int lisan[maxn];
int cnt, ans;
bool book[maxn];

void build(int p, int l, int r) {
    tr[p].l = l, tr[p].r = r;
    if (l == r) {
        tr[p].gg = 0; return;
    }
    int m = (l + r) >> 1;
    build(p << 1, l, m);
    build(p << 1 | 1, m + 1, r);
    tr[p].gg = 0;
}

void spread(int q) {
    if (tr[q].gg == 0) return;
    tr[q << 1].gg = tr[q].gg;
    tr[q << 1 | 1].gg = tr[q].gg;
    tr[q].gg = 0;
}

void update(int q, int l, int r, int v) {
    if (l <= tr[q].l && r >= tr[q].r) {
        tr[q].gg = v; return;
    }
    spread(q);
    int m = (tr[q].l + tr[q].r) >> 1;
    if (l <= m) update(q << 1, l, r, v);
    if (r > m) update(q << 1 | 1, l, r, v);
}

void ask(int q, int l, int r)
{
    if (tr[q].gg && !book[tr[q].gg])
    {
        ans++;
        book[tr[q].gg] = 1;
        return;
    }
    if (l == r) return;
    spread(q);
    int mid = (l + r) >> 1;
    ask(q << 1, l, mid);
    ask(q << 1 | 1, mid + 1, r);
}

int main() {
    //freopen("in.txt", "r", stdin);
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int t, n; sd(t);
    while (t--) {
        cnt = 0; ms(book, false); sd(n);
        for (int i = 0; i < n; ++i) {
            sdd(lg[i], rg[i]);
            lisan[cnt++] = lg[i];
            lisan[cnt++] = rg[i];
        }
        //离散化
        sort(lisan, lisan + cnt);
        int m = unique(lisan, lisan + cnt) - lisan;
        int t0 = m;
        for (int i = 1; i <= m; ++i)
            if (lisan[i] - lisan[i - 1] > 1)lisan[t0++] = lisan[i - 1] + 1;
        sort(lisan, lisan + t0);
        build(1, 1, t0);
        for (int i = 0; i < n; ++i) {
            int x = lower_bound(lisan, lisan + t0, lg[i]) - lisan + 1;
            int y = lower_bound(lisan, lisan + t0, rg[i]) - lisan + 1;
            //  cout <<x << " " << y << endl;
            update(1, x, y, i + 1);
        }
        ans = 0;
        ask(1, 1, t0);
        printf("%d\n", ans);
    }
    return 0;
}
posted @ 2020-07-31 15:53  RioTian  阅读(204)  评论(0编辑  收藏  举报