多个矩形边缘周长
来源:互联网 发布:315曝光的淘宝代购店铺 编辑:程序博客网 时间:2024/05/17 00:13
世事还是如此无常,关键是要有平常心!
http://www.cnblogs.com/Booble/archive/2010/10/10/1847163.html
详细耐心的解说,包您一看就懂,假一罚十!
以下是poj1177求多个矩形边缘周长的代码以及注释:
吐槽:WA了很久很久,原因是因为什么呢? maxn定义得太小了。
人家的坐标是 [-10000,10000],即使离散化,应该也有很多个点。
对于我容易错的地方:
R > m 要递归右子树
maxn
离散化的时候 开始的指针为1
//attention: //将线段树看成一个线段,它的每个点的意义是包括它本身的单位向后为一的线段#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define lson l,m, rt << 1#define rson m + 1, r, rt << 1 | 1#define maxn 22222using namespace std;//分别表示该区间的左端点、右端点表示的线段的右端点是否被覆盖bool lbd[maxn << 2],rbd[maxn << 2];int len[maxn << 2];//表示该节点区间所覆盖的长度int cnt[maxn << 2],numseg[maxn << 2];//分别表示该区间有几条线段覆盖、从远处看有几条线段struct Seg{int l , r , h , s;Seg() {}Seg(int a,int b,int c,int d):l(a) , r(b) , h(c) , s(d) {}bool operator < (const Seg &cmp) const {if (h == cmp.h) return s > cmp.s;return h < cmp.h;}}seg[maxn << 1];void push_up(int rt, int l, int r){ if(cnt[rt]){ lbd[rt] = rbd[rt] = true; len[rt] = r - l + 1; numseg[rt] = 2; }else if(l == r){ len[rt] = numseg[rt] = lbd[rt] = rbd[rt] = 0; }else{ lbd[rt] = lbd[rt << 1]; rbd[rt] = rbd[rt << 1 | 1]; len[rt] = len[rt << 1] + len[rt << 1 | 1]; numseg[rt] = numseg[rt << 1] + numseg[rt << 1 | 1]; if(lbd[rt << 1 | 1] && rbd[rt << 1]) numseg[rt] -= 2; }}void update(int L, int R, int c, int l ,int r, int rt){ if(L <= l && r <= R){ cnt[rt] += c; push_up(rt,l,r); return ; } int m = (l + r) >> 1; if(L <= m) update(L,R,c,lson); if(R > m) update(L,R,c,rson); push_up(rt,l,r);}int main(){ int n,a,b,c,d,s; int ret; while(scanf("%d",&n)!= EOF){ s = 0; ret = 0; int lt = 1000000, rt = - 100000; memset(len,0,sizeof(len)); memset(numseg,0,sizeof(numseg)); memset(cnt,0,sizeof(cnt)); memset(lbd,0,sizeof(lbd)); memset(rbd,0,sizeof(rbd)); for(int i = 0; i < n; i ++){ scanf("%d%d%d%d",&a,&b,&c,&d); lt = min(lt,a); rt = max(rt,c); //1表示矩形的下边 seg[s ++] = Seg(a,c,b,1); //-1表示矩形的上边。 //我是从下往上扫描,所以遇到下边即插入,遇到上边即删除 //由update里面的cnt[rt] += c 反应 seg[s ++] = Seg(a,c,d,-1); } sort(seg,seg+ s); //排序保证从下往上扫描 int last = 0; seg[s] .h = 0; for(int i = 0; i < s ; i ++){ if(seg[i].l <seg[i].r) //正因为线段树的定义,这里才插入的是 r - 1 update(seg[i].l,seg[i].r - 1,seg[i].s,lt,rt,1); ret += abs(len[1] - last); //差值 ret += numseg[1] * (seg[i + 1].h - seg[i].h); //线段数 * 统计区间长度 last = len[1]; } printf("%d\n",ret); } return 0;}int bin(int low, int high, double key,double X[]){ while(low < high){ int mid = (low + high) >> 1; if(X[mid] < key) low = mid + 1; else high = mid; } return low;}
- 多个矩形边缘周长
- hdu1828 矩形周长并
- 线段树 矩形周长
- 矩形区域边缘
- 矩形区域边缘
- 矩形 面积并 && 周长并
- 凸多边形最小周长外接矩形
- 矩形的周长及面积
- raptor程序求矩形周长
- 5-计算矩形的周长
- 矩形的周长和面积
- 输入多个半径,求面积、周长
- 边缘检测后计算区域周长
- poj 1151 Atlantis(多矩形面积) + poj 1177Picture(多矩形周长) 线段树进阶
- 使用继承与多态思想编写矩形,等边三角形,圆,求周长与面积
- d003: 计算矩形的周长和面积
- Poj1177(求矩形并的轮廓周长)
- HUD 1828 Picture 矩形周长/线段树
- 中国人该懂的知识
- C++笔记(一)explicit
- 单击 radio使在 "选中" 与 "未选中" 之间切换
- Android开发--身高体重指数(BIM)计算--添加对话框(Dialog)(设计对话框、定义调用点、实体对话框、重构、添加按钮)
- OnIdle
- 多个矩形边缘周长
- zoj2782------------------Q
- ring0和ring3的区别
- FrameWork
- Beat the Spread! (P2301)
- power Designer 数据库建模
- Tar打包、压缩与解压缩到指定目录的方法
- sed删除文件中的每行前n个字符
- 银行卡网络安全系统的三级密钥体系