hdu 1542 Atlantis 矩形面积并
2015-10-31 02:11
411 查看
// hdu 1542 Atlantis 矩形面积并 // // 解题思路: // // 将矩形沿着x轴或者y轴切割.然后求和 // 具体做法: // 将每个矩形看成是两条线段.将x方向 // 坐标离散化.给每个线段一个值,下面线段 // 为1,上面线段为-1.将这些线段映射到线段 // 树上.具体做法是,只要保存线段的左端点就 // 可以了.然后是线段树的基本操作了.更新成 // 段更新,查询是整个区间的值就是sum[1].仔细 // 理解倒也不是很难.强调一下,线段树保存的是 // 线段,并不是单个节点.计算sum的时候要多加 // 注意. #include <cstring> #include <algorithm> #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <vector> #include <queue> #define For(x,a,b,c) for (int x = a; x <= b; x += c) #define Ffor(x,a,b,c) for (int x = a; x >= b; x -= c) #define cls(x,a) memset(x,a,sizeof(x)) using namespace std; typedef long long ll; const double PI = acos(-1.0); const double EPS = 1e-10; const int MAX_N = 500 + 8; const double INF = 1e9; int N,M; double pos[MAX_N]; struct Seg{ double l,r,h; int cov; Seg(){ } Seg(double a,double b,double c,int cov):l(a),r(b),h(c),cov(cov){ } bool operator < (const Seg& other) const{ return h < other.h; } }s[MAX_N]; struct InterverTree{ #define ls(x) (x << 1) #define rs(x) (x << 1 | 1) int cov[MAX_N<<2]; double sum[MAX_N<<2]; void push_up(int rt,int L,int R){ if (cov[rt]) sum[rt] = pos[R + 1] - pos[L]; // 这条线段已经插入 else if (L == R) sum[rt] = 0; // 到了叶子节点,并且没有被插入到线段树中 else sum[rt] = sum[ls(rt)] + sum[rs(rt)]; } void update(int rt,int L,int R,int ql,int qr,int v){ if (ql <= L && R <= qr){ cov[rt] += v; push_up(rt,L,R); // 如果更新的是单个节点不加这里是会出错的 return ; } int M = (L + R) >> 1; if (ql <= M) update(ls(rt),L,M,ql,qr,v); if (M < qr) update(rs(rt),M+1,R,ql,qr,v); push_up(rt,L,R); } }it; void print(int n){ for (int i = 1 ;i < n;i ++){ printf("%lf ",pos[i]); } puts(""); } void input(){ int k = 1; for (int i = 1 ;i <= N;i ++){ double a,b,c,d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); pos[k] = a; s[k++] = Seg(a,c,b,1); pos[k] = c; s[k++] = Seg(a,c,d,-1); } sort(pos+1,pos+k); sort(s+1,s+k); int m = unique(pos + 1, pos + k) - pos; // 离散化 //print(m); //it.build(1,1,k-1); cls(it.sum,0); cls(it.cov,0); double res = 0; for (int i = 1 ;i < k - 1; i++){ int l = lower_bound(pos+1,pos + m,s[i].l) - pos; // 离散化操作 int r = lower_bound(pos+1,pos + m,s[i].r) - pos - 1; // 为什么-1,这里是插入线段的左端点 //cout << l << " " << r << " " << s[i].l << " " << s[i].r << endl; if (l <= r) it.update(1,1,k-1,l,r,s[i].cov); //printf("sum[1] = %lf\n",it.sum[1]); res += it.sum[1] *(s[i + 1].h - s[i].h); } printf("Total explored area: %.2lf\n",res); puts(""); } int main(){ int t; //freopen("1.in","r",stdin); int kase = 1; while(scanf("%d",&N)!=EOF && N){ printf("Test case #%d\n",kase++); input(); } }
相关文章推荐
- HDU 1542 Atlantis(线段树求矩形面积并)
- POJ 1177 Picture
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- 【HDU1542】Atlantis【线段树】【矩形面积并】
- 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线【线段树】【矩形面积并】
- Codeforces Round #337 (Div. 2) D.Vika and Segments
- HDU 1542 —— Atlantis 【矩形面积并:扫描线】
- 夜深人静写算法(七)- 线段树
- 层叠
- 两个简单的前台显示构架01
- AngularJS 指令(Directivce )一
- 51nod 1183 编辑距离
- JS--WIKI
- MongoDB创建系统管理员账户和数据库管理员账户
- 特殊性
- Golang time包的定时器/断续器
- 点对点-客户端服务器 ( peer to peer Client & Server )
- PHP 7 有些什么值得期待?(一)
- CSS继承
- [2011]:多项式求和