hdu1828&poj1177(线段树求矩形交周长,扫描线)
来源:互联网 发布:linux系统的命令 编辑:程序博客网 时间:2024/05/21 07:46
题目链接:hdu1828 poj1177
这篇博客讲的比较好理解:Click
/*hdu 矩形周长,扫描线*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson rt<<1#define rson rt<<1|1const int N = 5010;int x[N<<1];struct node{ int l,r,cov; bool lseg,rseg;//表示某个区间最左边和最右边是否有下底边多于上底边 int sum;//下底边的长度 int segnum;//没有被覆盖的竖边的个数}s[N<<2];struct seg{ int l, r, h, c; seg(){} seg(int x1, int x2, int y, int cc):l(x1),r(x2),h(y),c(cc){} bool operator < (const seg &cmp) const{ if(h == cmp.h) return c > cmp.c;//这里一定不能去掉,比如这组数据:2 0 0 4 4 0 4 4 8 return h < cmp.h; }}ss[N<<1];void pushup(int rt){ if(s[rt].cov){ s[rt].sum = x[s[rt].r+1] - x[s[rt].l]; s[rt].segnum = 2;//竖边个数为2 s[rt].lseg = s[rt].rseg = true; } else if(s[rt].l == s[rt].r){//叶子结点 s[rt].sum = s[rt].segnum = 0; s[rt].lseg = s[rt].rseg = false; } else{ s[rt].sum = s[lson].sum + s[rson].sum; s[rt].segnum = s[lson].segnum + s[rson].segnum; s[rt].lseg = s[lson].lseg; s[rt].rseg = s[rson].rseg; if(s[lson].rseg && s[rson].lseg) s[rt].segnum -= 2;//两个矩形相交(底边区域有重合)则减少两条竖边 }}void build(int l, int r, int rt){ s[rt].l = l; s[rt].r = r; s[rt].cov = s[rt].sum = s[rt].segnum = 0; s[rt].lseg = s[rt].rseg = false; if(l == r) return; int mid = (l+r) >> 1; build(l, mid, lson); build(mid+1, r, rson);}void updata(int l, int r, int c, int rt){ if(l <= s[rt].l && s[rt].r <= r){ s[rt].cov += c; pushup(rt); return; } int mid = (s[rt].l + s[rt].r) >> 1; if(l <= mid) updata(l, r, c, lson); if(mid < r) updata(l, r, c, rson); pushup(rt);}int main(){ int n,x1,x2,y1,y2,i,j; while(~scanf("%d",&n)) { int m = 0; for(i = 0; i < n; i ++){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ss[m] = seg(x1, x2, y1, 1); x[m++] = x1; ss[m] = seg(x1, x2, y2, -1); x[m++] = x2; } sort(x, x+m); sort(ss, ss+m); int k = 1; for(i = 1; i < m; i ++) if(x[i] != x[i-1]) x[k++] = x[i]; build(0, k, 1); int ans = 0, front = 0; for(i = 0; i < m; i ++){ int l = lower_bound(x, x+k, ss[i].l) - x; int r = lower_bound(x, x+k, ss[i].r) - x - 1; if(l <= r) updata(l, r, ss[i].c, 1); ans += s[1].segnum*(ss[i+1].h - ss[i].h);//竖边增加的总长 ans += abs(s[1].sum - front);//底边增加的总长 front = s[1].sum; } printf("%d\n",ans); } return 0;}
0 0
- hdu1828&poj1177(线段树求矩形交周长,扫描线)
- POJ1177 HDU1828 Picture,线段树求矩形并周长
- hdu1828 线段树扫描线求矩形面积的周长
- hdu1828线段树扫描线求周长
- 【poj1177】Picture(矩形周长并+线段树+扫描线)
- hdu 1828、poj1177求矩形周长并 线段树 扫描线
- poj1177[IOI1998]Picture (扫描线+离散化+线段树,求矩形周长并)
- hdu1828 Picture(扫描线+矩形周长并+线段树)
- hdu1828 Picture(线段树+扫描线+矩形周长并)
- hdu1828(线段树+扫描线求周长)
- hdu1828 Picture (线段树+扫描线)(求周长并)
- HDU1828 Picture(线段树+扫描线求周长并)
- hdu1828-Picture 线段树+扫描线 求周长并
- 线段树扫描线(周长并)hdu1828
- poj1177 Picture 扫描线求矩形周长并
- poj 1177 线段树+扫描线 求矩形交的周长
- 【POJ1177】【HDU1828】【codevs2149】矩形面积周长并
- hdu1828[扫描线矩形周长并]
- 杂七杂八
- uml里面的依赖和关联
- 主要开源协议一览
- 编程之美,大神和它的三个小伙伴
- 决策树ID3算法
- hdu1828&poj1177(线段树求矩形交周长,扫描线)
- 1.线性表
- IDL keyword_set 使用细节
- Servlet生命周期
- TCL与c/c++的互相调用
- myeclipse链接sql数据库
- Intellij Idea12第一个安卓程序开发(HelloWorld)及简单讲解Android
- A Bug's Life
- HDU2159(二维背包问题)