Poj2528Mayor's posters线段树

  先贴,明天再补。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include<math.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn = 44444;
int color[maxn << 2];
int vis[maxn];
int q[maxn];
int q1[maxn];
int l[maxn];
int r[maxn];
int Hash[maxn];
void down(int rt)
{
    if (color[rt]){
        color[rt << 1] = color[rt << 1 | 1] = color[rt];
        color[rt] = 0;
    }
}

void build(int l, int r, int rt)
{
    color[rt] = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
}

void update(int L, int R, int add, int l, int r, int rt)
{
    if (L <= l&&r <= R){
        color[rt] = add; return;
    }
    down(rt);
    int mid = (l + r) >> 1;
    if (L <= mid) update(L, R, add, lson);
    if (R>mid) update(L, R, add, rson);
}

void ask(int l, int r, int rt)
{
    if (color[rt]){
        Hash[color[rt]] = 1; return;
    }
    int mid = (l + r) >> 1;
    ask(lson); ask(rson);
}

int erfen(int key, int a[], int len)
{
    int l = 0; int r = len - 1;
    while (l <= r){
        int mid = (l + r) >> 1;
        if (a[mid] == key) return mid + 1;
        if (a[mid]<key) l = mid + 1;
        if (a[mid]>key) r = mid - 1;
    }
}
int cmp(const int &a, const int &b)
{
    return a<b;
}
int main()
{
    int Icase, n;
    int ans, ans1;
    scanf("%d", &Icase);
    while (Icase--){
        ans = 0; ans1 = 0;
        memset(Hash, 0, sizeof(Hash));
        scanf("%d", &n);
        for (int i = 0; i<n; i++){
            scanf("%d%d", &l[i], &r[i]);
            q[ans++] = l[i]; q[ans++] = r[i];
        }
        sort(q, q + ans, cmp);
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i<ans - 1; i++){
            if (q[i] == q[i + 1]) vis[i + 1] = 1;
        }
        int ans1 = 0;
        for (int i = 0; i<ans; i++)
        if (!vis[i]) q1[ans1++] = q[i];
        for (int i = 0; i<n; i++){
            l[i] = erfen(l[i], q1, ans1); r[i] = erfen(r[i], q1, ans1);
        }
        build(1, ans1, 1);
        for (int i = 0; i<n; i++){
            update(l[i], r[i], i + 1, 1, ans1, 1);
        }
        ask(1, ans1, 1);
        int gg = 0;
        for (int i = 1; i <= n; i++)
        if (Hash[i]) gg++;
        cout << gg << endl;
    }
    return 0;
}

Poj2528Mayor's posters线段树,布布扣,bubuko.com

Poj2528Mayor's posters线段树

时间: 2025-01-01 12:31:15

Poj2528Mayor's posters线段树的相关文章

poj2528--Mayor&#39;s posters(线段树+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41785   Accepted: 12164 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ2528Mayor&#39;s posters[线段树 离散化]

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59683   Accepted: 17296 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ2528Mayor&#39;s posters 线段树,离散化技巧

题意:一个坐标轴从1~1e7,每次覆盖一个区间(li,ri),问最后可见区间有多少个(没有被其他区间挡住的) 线段树,按倒序考虑,贴上的地方记为1,每次看(li,ri)这个区间是否全是1,全是1就说明在它后面贴的把它给挡住了,否则该海报可见. 然后就愉快的MLE了.... 再看看数据范围,离散化如下,比如如果海报的左右端点如下 那图中橙色的一块的大小其实对结果没有影响,可以把他们都缩为1 最后离散化结果如下图: 代码: 1 #include <algorithm> 2 #include <

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

Poj 2528 Mayor&#39;s posters (线段树+离散化)

题目连接: http://poj.org/problem?id=2528 题目大意: 有10000000块瓷砖,n张海报需要贴在墙上,每张海报所占的宽度和瓷砖宽度一样,长度是瓷砖长度的整数倍,问按照所给海报顺序向瓷砖上贴海报,最后有几张海报是可见的? 解题思路: 因为瓷砖块数和海报张数多,首选线段树,如果按照常规的建树方式,把瓷砖当做数的节点,肯定会MTL......... 所以我们可以用海报的起点和终点当做树的节点,这样树的节点才有20000个,但是这样建树的话,求海报覆盖了那些节点会很复杂,

poj 2528 Mayor&#39;s posters(线段树)

题目链接:http://poj.org/problem?id=2528 思路分析:线段树处理区间覆盖问题,也可以看做每次给一段区间染不同的颜色,最后求在整段区间上含有的所有颜色种类数: 注意由于区间太大,所以需要离散化: 区间更新:对于线段树的每个结点,标记颜色,初始时没有颜色,标记为0:当更新时,使用延迟标记,需要标记传递到子节点: 区间查询:使用深度优先查询线段树,当某个子节点的颜色不为0时,即停止深度优先搜索,并在map中查询是否已经记录该段区间的颜色: 代码如下: #include <i

Mayor&#39;s posters(线段树之点的成段更新加离散化)

bin神的萌萌哒专题 这道题目也是简单区间更新的线段树题目,不过题目的数据范围很大,直接搞,时间空间的花费都会异常的高,所以就要用到离散化来优化时间空间复杂度. 何为离散化?........................ 简单地说就是对于给出的庞大数据进行一种数据上的缩小. 比如给你一段(1,10000)的区间,由于我们要的不是其区间长度,我们只需要知道这段区间的状态 如何,于是我们可以忽视其长度,把其表示成(1,2)这个区间长度极小的区间,这相当于物理上的质点. 当我们处理的问题上与其区间长

POJ 2528 Mayor&#39;s posters 线段树成段更新+离散化

题目来源:POJ 2528 Mayor's posters 题意:很多张海报贴在墙上 求可以看到几张海报 看那两张图就行了 第一张俯视图 思路:最多2W个不同的数 离散化一下 然后成段更新 a[rt] = i代表这个区间是第i张报纸 更新玩之后一次query cover[i]=1代表可以看到第i张报纸 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const

poj 2528 Mayor&#39;s posters 线段树区间更新

Mayor's posters Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at al