51nod 1206:Picture 求覆盖周长
来源:互联网 发布:wpf编程宝典c 编辑:程序博客网 时间:2024/05/11 23:38
1206 Picture
题目来源: IOI 1998
基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
收藏
关注
给出平面上的N个矩形(矩形的边平行于X轴和Y轴),求这些矩形组成的所有多边形的周长之和。
例如:N = 7。(矩形会有重叠的地方)。
合并后的多边形:
多边形的周长包括里面未覆盖部分方块的周长。
Input
第1行:1个数N。(2 <= N <= 50000)第2 - N + 1行,每行4个数,中间用空格分隔,分别表示矩形左下和右上端点的坐标。(-1000000 <= X[i], Y[i] <= 1000000)
Output
输出多边形的周长。
Input示例
7-15 0 5 10-5 8 20 2515 -4 24 140 -6 16 42 15 10 2230 10 36 2034 0 40 16
Output示例
228
最近真的是被线段树扫描线搞得心力憔悴,刚刚才把poj上面求面积的弄懂,然后又遇到了求周长的。
思想和求面积是差不多的,变化就是多了一个line,就是当前的线段树分成了几段,这个在求面积的时候不会用到,但是求周长会用到。比如[1,1][2,2]就只有1段,[1,1][3,3]在线段树[1,3]的节点中就分成了两段。
第二点就是注意
tree[root].interval=tree[root*2+1].interval+tree[root*2+2].interval-tree[root*2+1].Rcover*tree[root*2+2].Lcover;
计算分成了多少块 是左子树的分块数+右子树的分块数,为了防止左子树的右边和右子树的左边连在一块,所以还要把这部分扣掉。
第三点就是注意排序,如果在x值相等的情况下,要将入边放在前面先处理,出边后处理。
代码:
#include <iostream>#include <algorithm>#include <cmath>#include <vector>#include <string>#include <cstring>#pragma warning(disable:4996)using namespace std;struct li{int x,y1,y2;int bLeft;}line[500005];int y[500005];int n;struct no{int L;int R;int cover;int Lcover;int Rcover;int interval;int m;}tree[500005];void buildtree(int root,int L,int R){tree[root].L=L;tree[root].R=R;tree[root].cover=0;tree[root].Lcover=0;tree[root].Rcover=0;tree[root].interval=0;tree[root].m=0;if(L!=R){int mid = (L+R)/2;buildtree(root*2+1,L,mid);buildtree(root*2+2,mid+1,R);}}void insert(int root,int L,int R){if(tree[root].L==L&&tree[root].R==R){tree[root].cover++;tree[root].m = y[R+1]-y[L];tree[root].Lcover=1;tree[root].Rcover=1;tree[root].interval=1;return;}else{int mid = (tree[root].L + tree[root].R)/2;if(R<=mid){insert(root*2+1,L,R);}else if(L>=mid+1){insert(root*2+2,L,R);}else{insert(root*2+1,L,mid);insert(root*2+2,mid+1,R);}}if(tree[root].cover==0){tree[root].m = tree[root*2+1].m +tree[root*2+2].m;tree[root].Lcover=tree[root*2+1].Lcover;tree[root].Rcover=tree[root*2+2].Rcover;tree[root].interval=tree[root*2+1].interval+tree[root*2+2].interval-tree[root*2+1].Rcover*tree[root*2+2].Lcover;}}void dele(int root,int L,int R){if(tree[root].L==L&&tree[root].R==R){tree[root].cover--;}else{int mid = (tree[root].L + tree[root].R)/2;if(R<=mid){dele(root*2+1,L,R);}else if(L>=mid+1){dele(root*2+2,L,R);}else{dele(root*2+1,L,mid);dele(root*2+2,mid+1,R);}}if(tree[root].cover<=0&&tree[root].L==tree[root].R){tree[root].m=0;tree[root].Lcover=0;tree[root].Rcover=0;tree[root].interval=0;}else if(tree[root].cover<=0){tree[root].m = tree[root*2+1].m +tree[root*2+2].m;tree[root].Lcover=tree[root*2+1].Lcover;tree[root].Rcover=tree[root*2+2].Rcover;tree[root].interval=tree[root*2+1].interval+tree[root*2+2].interval-tree[root*2+1].Rcover*tree[root*2+2].Lcover;}}bool cmp(struct li line1, struct li line2){if (line1.x == line2.x)return line1.bLeft > line2.bLeft;return (line1.x < line2.x);}template <class F,class T> F bin_search(F s,F e,T val) { F L = s; F R = e-1; while(L<=R) { F mid = L + (R-L)/2; if(!(*mid<val || val < *mid)) { return mid; } else if(val < *mid) { R = mid -1; } else { L= mid + 1; } } } int main(){//freopen("i.txt","r",stdin);//freopen("o.txt","w",stdout);int i,x1,x2,y1,y2,yc,lc;scanf("%d",&n);yc=0;lc=0;for(i=0;i<n;i++){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);y[yc++]=y1;y[yc++]=y2;line[lc].x=x1;line[lc].y1=y1;line[lc].y2=y2;line[lc].bLeft = 1;lc++;line[lc].x=x2;line[lc].y1=y1;line[lc].y2=y2;line[lc].bLeft = 0;lc++;}sort(line,line+lc,cmp);sort(y,y+yc);yc=unique(y,y+yc)-y;buildtree(0,0,yc-1-1);int preme=0;int now_m=0;int now_line=0;for(i=0;i<=lc-1;i++){int L=bin_search(y,y+yc,line[i].y1)-y; int R=bin_search(y,y+yc,line[i].y2)-y; if(line[i].bLeft) { insert(0,L,R-1); } else { dele(0,L,R-1); }if(i>=1)preme += 2*now_line*(line[i].x-line[i-1].x);preme += abs(tree[0].m-now_m);now_m=tree[0].m;now_line=tree[0].interval;}printf("%d\n",preme);//system("pause");return 0;}
0 0
- 51nod 1206:Picture 求覆盖周长
- POJ 1177 Picture(扫描线求周长)
- HDU 1828 Picture 扫描线 求周长
- 求矩形并的周长 poj 1177 picture
- poj 1177 Picture(线段树求矩形周长并)
- POJ1177 HDU1828 Picture,线段树求矩形并周长
- hdu 1828 poj 1177 picture 求周长并
- HDU - 1828 Picture (线段树求并周长)
- POJ 1177 & HDU 1828 Picture(扫描线 + 求周长)
- poj1177 Picture 扫描线求矩形周长并
- poj 1177 Picture 【线段树 扫描线 求轮廓周长】
- hdu1828 Picture (线段树+扫描线)(求周长并)
- hdu 1828 Picture【扫描线求周长模板题】
- HDU1828 Picture(线段树+扫描线求周长并)
- POJ 1177 Picture(线段树+离散化 求周长)
- usaco Picture(离散化求线段周长)
- hdu1828-Picture 线段树+扫描线 求周长并
- POJ-1177 Picture (线段树 求矩形周长)
- NSbundle
- win7 x64双机联调
- C++模板函数
- 按位非运算符“~”
- soket概览
- 51nod 1206:Picture 求覆盖周长
- java拾遗之关键字static
- js中if判断表达式
- 设置centos 系统时间与物理主机一致
- Android 在ScorllView中ListView和GridView冲突解决方案
- LeetCode Missing Number
- c++ for_each
- bind9支持edns-client-subnet
- java自带线程池和队列详细讲解