Mayor's posters 线段树+离散化+桶

在这里插入图片描述在这里插入图片描述在这里插入图片描述

简单说下题意:就是在一个宽1e7墙上面贴n张海报,第i张海报的起点是li,终点是ri,显然海报会覆盖别的海报。问依次贴完n张海报之后最后能看见几张海报。


题目要求最后能看见多少张海报,那么我们将每张海报都分别标上序号1,2,3…n。然后线段树修改区间,最后看线段树最底层有多少种数字即可。


需要注意的几点:

  • 海报终点可能到1e7,我们要做的区间修改以及最后桶排计数工作量就会非常大,但是只有20000张海报,我们可以进行离散化,这样最多40000个数据。

  • 由于这里的区间修改是完全覆盖原区间,因此我们更新区间的时候只需更新懒标即可。最后更新完所有区间之后,遍历整棵树,下传所有懒标,再数最底层的不同数字有多少即可。

AC代码:

//https://blog.csdn.net/hesorchen
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define ll long long
#define endl "\n"
#define INF 0x3f3f3f3f
#define MAX 100010
#define mod 1000000007
struct node
{
    int l, r, val, k, lazy;
} tr[MAX * 4];
struct node2
{
    int l, r;
} p1[MAX];
int p2[MAX * 2];
int ct2 = 1, ct3 = 1;
void build(int k, int l, int r)
{
    tr[k].l = l;
    tr[k].r = r;
    if (l == r)
    {
        tr[k].val = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(k * 2, l, mid);
    build(k * 2 + 1, mid + 1, r);
}
void pushdown(int k)
{
    if (tr[k].l == tr[k].r)
    {
        tr[k].lazy = 0;
        return;
    }
    if (tr[k].lazy)
    {
        tr[k * 2].lazy = tr[k].lazy;
        tr[k * 2 + 1].lazy = tr[k].lazy;
        tr[k].lazy = 0;
        return;
    }
}
void change(int k, int l, int r, int y)
{
    if (tr[k].l == l && tr[k].r == r)
    {
        tr[k].lazy = y;
        return;
    }
    pushdown(k);
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (r <= mid)
        change(k * 2, l, r, y);
    else if (l > mid)
        change(k * 2 + 1, l, r, y);
    else
    {
        change(k * 2, l, mid, y);
        change(k * 2 + 1, mid + 1, r, y);
    }
}
int tong[MAX * 2];
void updateans(int k)
{
    if (tr[k].lazy)
    {
        tr[k].val = tr[k].lazy;
        tr[k * 2].lazy = tr[k].lazy;
        tr[k * 2 + 1].lazy = tr[k].lazy;
    }
    if (tr[k].l == tr[k].r)
    {
        tong[tr[k].val] = 1;
        return;
    }
    updateans(k * 2);
    updateans(k * 2 + 1);
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        ct2 = 1, ct3 = 1;
        fill(tong, tong + MAX, 0);
        fill(p2, p2 + MAX, 0);
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d%d", &p1[i].l, &p1[i].r);
            p2[ct2++] = p1[i].l;
            p2[ct2++] = p1[i].r;
        }
        sort(p2 + 1, p2 + ct2);
        int new_end = unique(p2 + 1, p2 + ct2) - p2;
        int maxx = 0;
        for (int i = 1; i <= n; i++)
        {
            p1[i].l = lower_bound(p2 + 1, p2 + new_end, p1[i].l) - p2;
            p1[i].r = lower_bound(p2 + 1, p2 + new_end, p1[i].r) - p2;
            maxx = max(maxx, max(p1[i].l, p1[i].r));
        }
        build(1, 1, maxx);
        int cot = 1;
        for (int i = 1; i <= n; i++)
            change(1, p1[i].l, p1[i].r, cot++);
        updateans(1);
        int anss = 0;
        for (int i = 1; i <= maxx; i++)
            if (tong[i])
                anss++;
        cout << anss << endl;
    }
    return 0;
}
发布了76 篇原创文章 · 获赞 64 · 访问量 9328

猜你喜欢

转载自blog.csdn.net/hesorchen/article/details/104646858