poj2528(Mayor's posters)
题目地址:Mayor's posters
题目大意:
给你t组测试数据,按照题目给出的区间顺序贴上海报,问你最后能够看到多少张海报(不被完全覆盖的海报是表示可以看的海报计数加一)。
解题思路:
线段数+离散化(区间压缩映射)。
离散化 的大概思路 : 比如说给你一组 数据 1 4 1000 100000, 如果直接
开线段, 显然是浪费, 那么我们只要 进行 映射 :
1 1
4 2
1000 3
100000 4
接下来 我们只要对 1 2 3 4 建立线段树就行了 只需要
[1,4]的区间
离散化就相当于是先做映射,然后再建树。
墙上面的区间范围是1000W。 之间建树会内存超限,遍历二叉树搜索的时候也会时间超限,所以用到离散化,将范围缩小到海报数量1W*2. 然后在对各个区间编号。
需要注意是题目给出不相邻的端点离散后会变成相邻的端点,可能会造成错误,所以离散话的时候遇见相邻的端点时让hash阁一个点赋值。
我认为线段树的核心思想是尽量不往下搜索就不往下搜。
代码:
1 #include <algorithm> 2 #include <iostream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <string> 8 #include <bitset> 9 #include <vector> 10 #include <queue> 11 #include <stack> 12 #include <cmath> 13 #include <list> 14 //#include <map> 15 #include <set> 16 using namespace std; 17 /***************************************/ 18 #define ll long long 19 #define PI 3.1415927 20 /***************************************/ 21 22 const int M=20100; 23 struct tree 24 { 25 int col; 26 int left,right; 27 } node[M*8]; 28 int p[M*2][2]; 29 int cnt,ce; 30 int dis[10000100]; 31 void build__tree(int id,int l,int r) 32 { 33 int mid=(l+r)/2; 34 node[id].left=l; 35 node[id].right=r; 36 node[id].col=0; 37 if (l==r) 38 return ; 39 build__tree(id*2,l,mid); 40 build__tree(id*2+1,mid+1,r); 41 } 42 void updata(int id,int l,int r,int v) 43 { 44 int mid=(node[id].left+node[id].right)/2; 45 if (node[id].col) 46 return; 47 if (node[id].left==l&&node[id].right==r) 48 { 49 if (node[id].col==0) 50 { 51 node[id].col=1; 52 cnt+=ce; 53 ce=0; 54 } 55 return ; 56 } 57 if (r<=mid) 58 updata(id*2,l,r,v); 59 else if (l>mid) 60 updata(id*2+1,l,r,v); 61 else 62 { 63 updata(id*2,l,mid,v); 64 updata(id*2+1,mid+1,r,v); 65 } 66 if (node[id*2].col==1&&node[id*2+1].col==1) 67 node[id].col=1; 68 } 69 70 int main() 71 { 72 int cas; 73 scanf("%d",&cas); 74 while(cas--) 75 { 76 int n; 77 scanf("%d",&n); 78 int i,j; 79 int xu[M*2],d=0; 80 for(i=1;i<=n;i++) 81 { 82 scanf("%d%d",&p[i][0],&p[i][1]); 83 xu[d++]=p[i][0]; 84 xu[d++]=p[i][1]; 85 } 86 sort(xu,xu+d); 87 int ncount=unique(xu,xu+d)-xu; //去重函数,头文件iostream.h 88 int hash=0; 89 for(i=0;i<ncount;i++) 90 { 91 dis[xu[i]]=++hash; 92 if(xu[i]!=xu[i-1]+1&&i>0) 93 dis[xu[i]]=++hash; 94 } 95 build__tree(1,1,hash); 96 cnt=0; 97 for(i=n;i>=1;i--) 98 { 99 ce=1; 100 updata(1,dis[p[i][0]],dis[p[i][1]],1); 101 } 102 printf("%d\n",cnt); 103 memset(dis,0,sizeof(dis)); 104 } 105 return 0; 106 } 107 /* 108 1 109 3 110 1 10 111 1 3 112 6 10 113 */
屌丝终有逆袭日,*******。