hdu 1828、poj1177求矩形周长并 线段树 扫描线
来源:互联网 发布:js电子相册 编辑:程序博客网 时间:2024/05/05 20:21
hdu 1828 http://acm.hdu.edu.cn/showproblem.php?pid=1828
poj 1177 http://poj.org/problem?id=1177
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn= 5010;struct node{ int lef, rig, mid, cov;}seg[8*maxn];struct point{ int lef, rig, pos, flag; //flag为1, 下边, flag为-1 上边}px[2*maxn], py[2*maxn]; // px 为对y做线段树, py为对x做线段树int disx[2*maxn], disy[2*maxn]; //离散坐标, 下标为离散值int n, lenx, leny; //横纵坐标离散后长度__int64 ans;void init(){ int i, j, k, x1, y1, x2, y2; for( i=0; i<n; i++){ scanf("%d%d%d%d", &x1, &y1, &x2, &y2); px[i*2+1].lef= px[i*2].lef= y1; px[i*2+1].rig= px[i*2].rig= y2; px[i*2].pos= x1; px[i*2].flag= 1; px[i*2+1].pos= x2; px[i*2+1].flag= -1; py[i*2+1].lef= py[i*2].lef= x1; py[i*2+1].rig= py[i*2].rig= x2; py[i*2].pos= y1; py[i*2].flag= 1; py[i*2+1].pos= y2; py[i*2+1].flag= -1; disx[i*2]= x1; disx[i*2+1]= x2; disy[i*2]= y1; disy[i*2+1]= y2; }}bool cmp( point x, point y){ return x.pos < y.pos;}void disperse(){ sort( disx, disx+ 2*n); sort( disy, disy+ 2*n); lenx= unique(disx, disx+ 2*n)- disx; leny= unique(disy, disy+ 2*n)- disy; sort( px, px+ 2*n, cmp); //对y做线段树,按pos(即x)顺序由小及大排列 sort( py, py+ 2*n, cmp);}void maketree( int num, int lef, int rig){ seg[num].lef= lef; seg[num].rig= rig; seg[num].mid= (lef + rig) >> 1; seg[num].cov= 0; if( lef +1!= rig){ maketree( num*2, lef, seg[num].mid); maketree( num*2+ 1, seg[num].mid, rig); }}//1. 当seg[num].cov由0变1时,记录线段长度,并乘2,即上下对应两边长度和//2. 对于seg[num].cov== 0且 左右点相符, 同时为新加线段,而非已有线段向下更新时,计起长度//3. 若左右端点相符,且seg[num].cov>0时, seg[num].cov+= cov//4. 若左右端点相符,seg[num].cov==0,并且为已有线段向下更新,而非新加入线段,seg[num].cov+= cov//5. 对于某条seg[num].cov>0的线段,若要更新其一部分,即子线段,则先把这条线段的// seg[num].cov更新到其所有子节点,再把seg[num].cov赋为-1, 再对其子线段进行更新//6. tt 为1时,为新加线段,tt为0时,是已有线段向下更新//7. tmp为1,对y建的线段树,tmp为0, 对x建的线段树//8. 已经标记为-1的线段,不会再变为其他值int insert( int num, int lef, int rig, int cov, int tt, int tmp){ if( seg[num].cov == 0 && seg[num].lef== lef && seg[num].rig== rig && tt== 1){ seg[num].cov= 1; if( tmp== 1)return disy[rig]- disy[lef]; else return disx[rig]-disx[lef]; } if( seg[num].cov >= 0 && seg[num].lef == lef && seg[num].rig== rig){ seg[num].cov+= cov; return 0; } if( seg[num].cov > 0){ insert( num*2, seg[num].lef, seg[num].mid, seg[num].cov, 0, tmp); insert( num*2+1, seg[num].mid, seg[num].rig, seg[num].cov, 0, tmp); } seg[num].cov= -1; if( rig <= seg[num].mid) return insert( num*2, lef, rig, cov, tt, tmp); else if( lef >= seg[num].mid) return insert( num*2+1, lef, rig, cov, tt, tmp); else return insert( num*2, lef, seg[num].mid, cov, tt, tmp) + insert( num*2+1, seg[num].mid, rig, cov, tt, tmp);}int bx(int x){ //查找x的离散后坐标 int lef= 0, rig= lenx-1, mid; while( lef <= rig){ mid= (lef + rig) >> 1; if( disx[mid] < x) lef= mid+1; else if( disx[mid] > x) rig= mid- 1; else return mid; }}int by(int y){ int lef= 0, rig= leny-1, mid; while( lef <= rig){ mid= (lef + rig) >> 1; if( disy[mid] < y) lef= mid+1; else if( disy[mid] > y) rig= mid- 1; else return mid; }}int main(){ // freopen("1.txt", "r", stdin); int i, aa; while( scanf("%d", &n) != EOF){ init(); disperse(); ans= 0; //分别对对x、y 扫描线, 求长度并 maketree(1, 0, leny); for( i=0; i<2*n; i++){ ans+= insert(1, by(px[i].lef), by(px[i].rig), px[i].flag, 1, 1); } maketree(1, 0, lenx); for( i=0; i<2*n; i++){ ans+= insert(1, bx(py[i].lef), bx(py[i].rig), py[i].flag, 1, 0); } printf("%d\n", ans*2); } return 0;}
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- hdu1828&poj1177(线段树求矩形交周长,扫描线)
- 【poj1177】Picture(矩形周长并+线段树+扫描线)
- poj1177[IOI1998]Picture (扫描线+离散化+线段树,求矩形周长并)
- poj1177 Picture 扫描线求矩形周长并
- POJ1177 HDU1828 Picture,线段树求矩形并周长
- hdu 1828线段树扫描线求周长并
- hdu 1542 矩形面积并 &&hdu 1255 矩形面积交 && hdu 1828 矩阵周长并 线段树+扫描线入门
- hdu 1828 Picture(线段树扫描线矩形周长并)
- Poj1177(求矩形并的轮廓周长)
- 算法总结:【线段树+扫描线】&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828)
- poj 1177 || HDU 1828 Picture (线段树扫描线求 图形并的周长)
- HDU 1828 Picture (线段树扫描线求周长并 区间合并)
- 【POJ】1171 求矩形并的周长(线段树+扫描线+离散化)
- hdu1828 线段树扫描线求矩形面积的周长
- hdu 1828 Picture(线段树&扫描线&周长并)
- HDU 1828 线段树之扫描线之周长并
- hdu1828 Picture(扫描线+矩形周长并+线段树)
- MSP430------2
- [讨论]hnu 12450 Painting
- .每天对着电脑4-6小时的人必看
- RAD环境
- C++虚函数表解析
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- JSF动态生成组件
- POJ——2696
- android开发时,finish()跟System.exit(0)的区别
- JAVA 及 js 浮点数精确计算
- Struts、Hibernate复习 && 了解与Spring结合的SSH
- android连续按两次返回退出程序(完整代码)
- 使用wxWidgets开发跨平台的GUI程序-wxDevCpp
- < Unity 3D专栏 >U3D预制包,很好很强大 (二)