因为将每个单位都作为一个最小单元的话会爆内存的
所以,将海报的每个端点进行排序,将这些端点最为最小的区间。
毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了。
萌萌的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