POJ - 2528 Mayor's posters (离散化+线段树区间修改)

https://cn.vjudge.net/problem/POJ-2528

题意

给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张?

分析

海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间。

如果直接建树,就算不TLE,也会MLE。即单位区间长度太多。

其实10000张海报,有20000个点,最多有19999个区间。对各个区间编号,就是离散化。然后建树。

可以直接进行区间修改,最后再统计。

这里采用比较巧妙的方法,倒着来统计,每次看这个将覆盖的区间是否已经完全被覆盖了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define eps 0.0000000001
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1)
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = 10000 + 10;
const int maxm = 200000 + 10;
const int mod = 10007;

pii poster[maxn];
int x[maxn<<1];
int Hash[10000005];
struct ND{
    int l,r;
    bool covered;
}tree[maxn<<3];
void build(int rt,int l,int r){
    tree[rt].l=l;
    tree[rt].r=r;
    tree[rt].covered=false;
    if(l==r) return;
    int mid = (l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
}

void pushup(int rt){
    tree[rt].covered=tree[rt<<1].covered&tree[rt<<1|1].covered;
}

bool update(int rt,double l,double r){
    if(tree[rt].covered) return false;
    if(l<=tree[rt].l&&r>=tree[rt].r) return tree[rt].covered=true;
    bool res;
    if(tree[rt<<1].r>=r) res=update(rt<<1,l,r);
    else if(l>=tree[rt<<1|1].l) res=update(rt<<1|1,l,r);
    else{
        bool b1=update(rt<<1,l,tree[rt<<1].r);
        bool b2=update(rt<<1|1,tree[rt<<1|1].l,r);
        res=b1||b2;
    }
    pushup(rt);
    return res;
}
int n;
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int T,cas=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int cnt=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&poster[i].first,&poster[i].second);
            x[cnt++]=poster[i].first;
            x[cnt++]=poster[i].second;
        }
        sort(x,x+cnt);
        cnt=unique(x,x+cnt)-x;
        build(1,0,cnt-1);
        for(int i=0;i<cnt;i++) Hash[x[i]]=i;
        int res=0;
        for(int i=n-1;i>=0;i--){
            if(update(1,Hash[poster[i].first],Hash[poster[i].second]))
                res++;
        }
        printf("%d\n",res);
    }
    return 0;
}

---恢复内容结束---

POJ - 2528 Mayor's posters (离散化+线段树区间修改)

原文地址:https://www.cnblogs.com/fht-litost/p/9581931.html

时间: 2024-08-22 14:49:25

POJ - 2528 Mayor's posters (离散化+线段树区间修改)的相关文章

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

Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for

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

题意  在墙上贴n张海报  输入每张海报的的左右端点坐标  问最后可以看到多少张海报  能看到一点也是能看到 先把线段树初始化为0 输入一张海报  就把那个区间变成这张海报的序号  最后判断墙上有多少个不同的序号就行了 但是海报坐标的端点值高达10000000  直接用线段树会超时   但是注意到海报最多只有10000张  也就是最多有20000个不同的坐标  于是可以利用离散化的知识   把所有坐标排序 注意所有右端点坐标+1也要加入排序(注意1,10 ; 1,3;  7,10这种情况  如果

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

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

poj 2528 Mayor&#39;s posters(线段树区间覆盖、离散化)

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

POJ 2528——Mayor&#39;s posters——————【线段树区间替换、找存在的不同区间】

Mayor's posters Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2528 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been plac

poj 2528 Mayor&#39;s posters (线段树+区间离散)

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

POJ - 2528 - Mayor&#39;s posters 【线段树+离散化+补点】

http://poj.org/problem?id=2528 #include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; in

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

题目链接:Mayor's posters 题意:按顺序往墙上贴海报,可以重叠,问最后可以看到多少海报.(被覆盖的海报是看不到的) 注意: 因为数据比较大,所以不离散化,肯定爆内存. 还有就是,不能只是单纯的离散化,还要处理好点的边界 举个例子 4 2  10. 2  8 3  6 6  8 8  10 离散化后 2 3 6 8 10 1 2 3 4 5 覆盖掉了 1 5   和  1 4俩段 只剩下 2  3  .3  4. 4  5 答案是 3 但是正确答案是4 所以,离散化处理时要处理边界,

【POJ】2528 Mayor&#39;s posters ——离散化+线段树

Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city

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

这道题目让我又重新认识了一下离散化: 首先总结一下离散化的特点: 1)有时区间的端点并不是整数,或者区间太大导致建树内存开销过大而MLE,那么就需要进行离散化后再建树. 2)意思是将区间范围很大的数据集映射到较小的数据集,这样建树更加有效,或者说我们只取需要的值来用. 这个意思说到底就是进行映射,把原来很大的映射到一个较小的空间中去. 题意: 给定一些海报,它们可能相互重叠,告诉你每个海报的宽度(它们的高度都是一样的)和先后的叠放次序,问没有被完全盖住的海报有多少张? 这里我们注意到了数据的范围