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

因为将每个单位都作为一个最小单元的话会爆内存的

所以,将海报的每个端点进行排序,将这些端点最为最小的区间。

毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了。

萌萌的AC代码君贴上。

  1 //#define LOCAL
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <cmath>
  5 using namespace std;
  6
  7 int n;
  8 struct CPost
  9 {
 10     int L, R;
 11 }posters[10000 + 100];
 12 int x[20000 + 200];    //海报的端点瓷砖编号
 13 int hash[10000000 + 10];//hash[i]表示瓷砖i所处的离散化后的区间编号
 14
 15 struct CNode
 16 {
 17     int L, R;
 18     bool bCovered;    //区间[L, R]是否已经完全覆盖
 19     CNode *pLeft, *pRight;
 20 }Tree[1000000];
 21 int nNodeCount = 0;
 22 int Mid(CNode* pRoot)
 23 {
 24     return (pRoot->L + pRoot->R) / 2;
 25 }
 26 void BuildTree(CNode *pRoot, int L, int R)
 27 {
 28     pRoot->L = L;
 29     pRoot->R = R;
 30     pRoot->bCovered = false;
 31     if(L == R)
 32         return;
 33     ++nNodeCount;
 34     pRoot->pLeft = Tree + nNodeCount;
 35     ++nNodeCount;
 36     pRoot->pRight = Tree + nNodeCount;
 37     BuildTree(pRoot->pLeft, L, (L+R)/2);
 38     BuildTree(pRoot->pRight, (L+R)/2+1, R);
 39 }
 40 bool Post(CNode *pRoot, int L, int R)
 41 {//插入一张覆盖区间[L, R]的海报,返回true则说明该区间是部分或者全部可见的
 42     if(pRoot->bCovered)
 43         return false;
 44     if(pRoot->L == L && pRoot->R == R)
 45     {
 46         pRoot->bCovered = true;
 47         return true;
 48     }
 49     bool bResult;
 50     if(R <= Mid(pRoot))
 51         bResult = Post(pRoot->pLeft, L, R);
 52     else if(L >= Mid(pRoot) + 1)
 53         bResult = Post(pRoot->pRight, L, R);
 54     else
 55     {
 56         bool b1 = Post(pRoot->pLeft, L, Mid(pRoot));
 57         bool b2 = Post(pRoot->pRight, Mid(pRoot) + 1, R);
 58         bResult = b1 || b2;
 59     }
 60     //要更新的节点的覆盖情况
 61     if(pRoot->pLeft->bCovered && pRoot->pRight->bCovered)
 62         pRoot->bCovered = true;
 63     return bResult;
 64 }
 65
 66 int main(void)
 67 {
 68     #ifdef LOCAL
 69         freopen("2528in.txt", "r", stdin);
 70     #endif
 71     int t;
 72     int i, j, k;
 73     scanf("%d", &t);
 74     int nCaseNo = 0;
 75     while(t--)
 76     {
 77         ++nCaseNo;
 78         scanf("%d", &n);
 79         int nCount = 0;
 80         for(i = 0; i < n; ++i)
 81         {
 82             scanf("%d%d", &posters[i].L, &posters[i].R);
 83             x[nCount++] = posters[i].L;
 84             x[nCount++] = posters[i].R;
 85         }
 86         sort(x, x + nCount);
 87         nCount = unique(x, x + nCount) - x;//元素去重
 88         //将下面离散化
 89         int nIntervalNo = 0;
 90         for(i = 0; i < nCount; ++i)
 91         {
 92             hash[x[i]] = nIntervalNo;
 93             if(i < nCount - 1)
 94             {
 95                 if(x[i + 1] - x[i] == 1)
 96                     ++nIntervalNo;
 97                 else
 98                     nIntervalNo += 2;
 99             }
100         }
101
102         BuildTree(Tree, 0, nIntervalNo);
103         int nSum = 0;
104         for(i = n - 1; i >= 0; --i)
105         {//从后往前遍历每个海报是否可见
106             if(Post(Tree, hash[posters[i].L], hash[posters[i].R]))
107                 ++nSum;
108         }
109         printf("%d\n", nSum);
110     }
111     return 0;
112 }

代码君

POJ 2528 (线段树+离散化) Mayor's posters,布布扣,bubuko.com

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

时间: 2024-11-10 00:49:18

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

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

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

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

2016-08-15 题意:一面墙,往上面贴海报,后面贴的可以覆盖前面贴的.问最后能看见几种海报. 思路:可以理解成往墙上涂颜色,最后能看见几种颜色(下面就是以涂色来讲的).这面墙长度为1~1000 0000,一千万,确实很大.暴力的话肯定不行,除非..( you know). 正确的解法是用线段树,不过还得加上离散化,因为数据太大10000000啊. 先说一下离散化,这个其实就是压缩,把范围压缩,举个例子: 输入 : 1 3000    //涂第一种颜色 范围从1~10000      下面同

poj 2528(线段树+离散化) 市长的海报

http://poj.org/problem?id=2528 题目大意是市长竞选要贴海报,给出墙的长度和依次张贴的海报的长度区间(参考题目给的图),问最后你能看见的海报有几张 就是有的先贴的海报可能会被后贴的海报完全盖住,那就看不见了 这里就非常抽象的区间更新,墙的长度为建立线段树的总区间,每贴一张海报代表将这个区间的颜色涂为相应的,每张海报的颜色当然 都不相同,求最后又多少种颜色就行,但这里还要用到基础的离散化 离散化是把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率. 简单

POJ 2528 线段树+离散化

题意是给你n张海报,告诉你每张海报的宽度和先后顺序,海报会重叠,问你露在外面的海报有多少张?这题主要是离散化理解了好久,关键在于建hash表时不能选择最普通的一一对应,为什么?看了网上一组数据后瞬间就明白了:1,10  1,4  6,10. Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 51347   Accepted: 14875 Description The citizens of

Mayor&#39;s posters POJ - 2528 线段树区间覆盖

//线段树区间覆盖 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=100010; int flag; struct node{ int l,r; //vis 是这块区域是否完全被覆盖 bool vis; }tr[N<<2]; struct point { int id; int x

【线段树】Mayor&#39;s posters

[poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accepted: 19104 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elect

poj 2528 线段树+特殊离散化

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 51098   Accepted: 14788 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 线段树+延迟更新

题目链接:http://poj.org/problem?id=2528 题意: 在墙上贴海报,输入n(1<=n<=10000),表示n张海报,后n行输入 两整数l,r  ( 1<= l, r<= 1e9 ),表示海报从编号为l的石头一直贴到编号为r的石头,输入顺序即为粘贴顺序.问n张贴完之后,还能看到多少张海报. 思路: 显然区间操作,很容易联想到线段树操作,只不过区间 l,r 最大范围可达1e9,直接建树,内存必爆.   那么就需要避开1e9的数据,进行离散化,将区间变成(1到n

Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长

参考  https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include <algorithm> #define LEN 10000 using namespace std; struct Node { int left; int right; int count;//被覆盖次数 //所包含的区间数量,如三条[1,2],[2,3],[4,5]线段被覆盖,则line=2