POJ 2528 Mayor's posters 线段树+离散化
来源:互联网 发布:淘宝联盟链接打不开 编辑:程序博客网 时间:2024/04/30 13:01
题意: 在墙壁上贴海报,计算出看得见的张数。
题解:
线段树基础知识
从简单说起,线段树其实可以理解成一种特殊的二叉树。但是这种二叉树较为平衡,和静态二叉树一样,都是提前已经建立好的树形结构。针对性强,所以效率要高。这里又想到了一句题外话:动态和静态的差别。动态结构较为灵活,但是速度较慢;静态结构节省内存,速度较快。
接着回到线段树上来,线段树是建立在线段的基础上,每个结点都代表了一条线段[a , b]。长度为1的线段成为元线段。非元线段都有两个子结点,左结点代表的线段为[a , (a + b ) / 2],右结点代表的线段为[( a + b ) / 2 , b]。
图一就是一棵长度范围为[1 , 10]的线段树。
长度范围为[1 , L] 的一棵线段树的深度为log ( L - 1 ) + 1。这个显然,而且存储一棵线段树的空间复杂度为O(L)。
线段树支持最基本的操作为插入和删除一条线段。下面已插入为例,详细叙述,删除类似。
将一条线段[a , b] 插入到代表线段[l , r]的结点p中,如果p不是元线段,那么令mid=(l+r)/2。如果a<mid,那么将线段[a , b] 也插入到p的左儿子结点中,如果b>mid,那么将线段[a , b] 也插入到p的右儿子结点中。
插入(删除)操作的时间复杂度为O ( Log n )。
上面的都是些基本的线段树结构,但只有这些并不能做什么,就好比一个程序有输入没输出,根本没有任何用处。
最简单的应用就是记录线段有否被覆盖,并随时查询当前被覆盖线段的总长度。那么此时可以在结点结构中加入一个变量int count;代表当前结点代表的子树中被覆盖的线段长度和。这样就要在插入(删除)当中维护这个count值,于是当前的覆盖总值就是根节点的count值了。另外也可以将count换成bool cover;支持查找一个结点或线段是否被覆盖。
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define L(u) (u<<1)#define R(u) (u<<1|1)#define W 1000000#define N 10000struct TreeNode { int l,r,c;};TreeNode node[W*10];int l[N*2], r[N*2], cood[N*3];int ans, mark[N*2];void build ( int u, int l, int r ){ node[u].l = l; node[u].r = r; node[u].c = 0;if ( l == r ) return;int mid = ( l + r ) >> 1;build ( L(u), l, mid );build ( R(u), mid + 1, r );}void update ( int u, int l, int r, int c ){ if ( node[u].c == c ) return;if ( node[u].l == l && node[u].r == r ){node[u].c = c; return;}if ( node[u].c != -1 ){ node[L(u)].c = node[R(u)].c = node[u].c;node[u].c = -1; }int mid = (node[u].l + node[u].r) >> 1;if ( r <= mid ) update (L(u),l,r,c);else if ( l > mid ) update (R(u),l,r,c);else update (L(u),l,mid,c), update(R(u),mid+1,r,c);}void query ( int u ){if ( node[u].c != -1 ) {if( node[u].c && !mark[node[u].c] ) { mark[node[u].c] = 1; ans++; }return;}if ( node[u].l == node[u].r ) return;query ( L(u) );query ( R(u) );}int bfind ( int l, int r, int num ){ while ( l <= r ) { int mid = (l+r) >> 1; if ( cood[mid] == num ) return mid; if ( num < cood[mid] ) r = mid - 1; else l = mid + 1; } return -1;}int main(){int cs, n;scanf("%d",&cs);while ( cs-- ) { scanf("%d",&n); int i, j, a, b; for (i = 1; i <= n; i++) { scanf("%d%d",&l[i],&r[i]); cood[i] = l[i]; cood[i+n] = r[i]; } sort(cood+1,cood+1+n*2); for ( i = 2, j = 1; i <= n*2; i++ ) if ( cood[i] != cood[i-1] ) cood[++j] = cood[i]; build ( 1, 1, j ); for ( i = 1; i <= n; i++ ) { a = bfind ( 1, j, l[i] ); b = bfind ( 1, j, r[i] ); update ( 1, a, b, i ); } ans = 0; memset(mark,0,sizeof(mark)); query ( 1 ); printf("%d\n",ans); } return 0;}
- 离散化+线段树 POJ 2528 (Mayor's posters)
- POJ 2528 Mayor's posters(离散化+线段树)
- poj 2528 Mayor's posters 离散化 线段树
- POJ 2528 Mayor's posters 线段树+离散化
- poj 2528 Mayor's posters 线段树+离散化
- POJ 2528 Mayor's posters (线段树+离散化)
- POJ 2528 Mayor's posters(离散化+线段树)
- POJ 2528 Mayor's posters 线段树+离散化
- POJ 2528 Mayor's posters(线段树+离散化)
- POJ 2528 Mayor's posters (线段树+离散化)
- poj 2528 Mayor's posters(线段树+离散化)
- POJ 2528 Mayor's posters 线段树+离散化
- poj - 2528 - Mayor's posters 线段树+离散化
- poj 2528 Mayor's posters 线段树+离散化
- poj 2528 Mayor's posters(离散化+线段树)
- POJ 2528 Mayor's posters (线段树+离散化)
- poj 2528 Mayor's posters(离散化+线段树)
- POJ 2528 Mayor's posters 离散化线段树
- android ndk 学习
- Dojo1.6官方教程:连接DataGrid和Store
- poj 2253 Frogger
- HDU3912 Turn Right 模拟 2011 Multi-University Training Contest 8 - Host by HUST
- poj 1251 Jungle Roads
- POJ 2528 Mayor's posters 线段树+离散化
- poj 1269 Intersecting Lines
- poj 1258 Agri-Net
- poj 1797 Heavy Transportation
- poj 1789 Truck History
- poj 2485 Highways
- 探讨数据绑定表达式的语法
- 插入排序--希尔排序
- hdu acmsteps 2.1.3 cake