CSU 1292 Rectangles Intersection
2013-05-24 18:50
381 查看
原题链接:http://122.207.68.93/OnlineJudge/problem.php?id=1292
线段树+扫描线。这道题是典型的矩形面积并问题,乍一看109 * 109 * 105 超了long long,但这个无关紧要,其实如果总面积>1018 可以直接判断肯定有相交的面积了,这么一来,就是裸模版题了,贴膜板:
View Code
线段树+扫描线。这道题是典型的矩形面积并问题,乍一看109 * 109 * 105 超了long long,但这个无关紧要,其实如果总面积>1018 可以直接判断肯定有相交的面积了,这么一来,就是裸模版题了,贴膜板:
#include "cstdio" #include "iostream" #include "algorithm" #define lson cur<<1 #define rson cur<<1|1 using namespace std; typedef long long LL; const int maxn = 200000 + 5; const int root = 1; struct seg //扫描线结构体 { int x, y1, y2; //扫描线数据 x横坐标 y1,y2,上下顶点 short flag; //标记是进入的还是出来的(对于一个矩形所产生的两条扫描线来说) seg() {}; seg(int a, int b, int c, short d):x(a), y1(b), y2(c), flag(d) {} inline friend bool operator <(seg a, seg b) { return a.x < b.x; //用于sort } } ss[maxn]; int m; //扫描线总数 int y[maxn]; //离散值-->实际值 struct node //线段树结构体 (加入的是扫描线(纵向)) { int l, r, cover; //左右范围(实际上没有用),cover:是否完全覆盖 int yl, yr, len; //实际范围和长度 node() {} node(int a, int b, int c, int d, short f, int g) { l = a, r = b, yl = c, yr = d, cover = f, len = g; } } a[maxn << 2]; inline void build(int cur, int l, int r) //建立线段树 { a[cur] = node(l, r, y[l], y[r], 0, 0); if (l+1 == r) return ; int mid = (l+r) >> 1; build(lson, l, mid); build(rson, mid, r); } inline void pushup(int cur) //计算当前cur结点覆盖的长度(纵向) { if (a[cur].cover > 0) a[cur].len = a[cur].yr - a[cur].yl; //当前结点被完全覆盖 else if (a[cur].l+1 == a[cur].r) a[cur].len = 0; //叶节点但已经被去除掉了(cover<=0) else a[cur].len = a[lson].len + a[rson].len; //自身未被完全覆盖,向子节点求助 } inline void updata(int cur, seg b) //更新i.e加入边操作 { if (b.y1 == a[cur].yl && b.y2 == a[cur].yr) { //被加入的边完全覆盖 a[cur].cover += b.flag; //是否被抛弃 pushup(cur); //计算长度 return; } if (b.y2 <= a[rson].yl) updata(lson, b); else if (b.y1 >= a[lson].yr) updata(rson, b); else { seg tmp = b; //将b拆开付给lson rson tmp.y2 = a[lson].yr; updata(lson, tmp); tmp = b, tmp.y1 = a[rson].yl; updata(rson, tmp); } pushup(cur); return; } int main() { int t, n; int x1, x2, y1, y2; LL area; cin >> t; while(t--) { m = 0; scanf("%d", &n); area = 0; for (int i = 1; i <= n; i ++) { scanf("%d %d %d %d", &x1, &y1, &x2, &y2); area += (LL)(x2 - x1) * (LL)(y2 - y1); ss[++m] = seg(x1, y1, y2, 1), y[m] = y1; //建立扫描线 ss[++m] = seg(x2, y1, y2, -1), y[m] = y2; } if(area < 0 || area > 1000000000000000000ll) { cout << "Bad" << endl; continue; } sort(ss+1,ss+1+m); sort(y+1,y+1+m); //离散化 build(root, 1, m); //建树 LL sum(0); for (int i = 1; i < m; i++) //依次加边 { updata(root, ss[i]); sum += (LL)a[root].len * (LL)(ss[i+1].x - ss[i].x); //计算此时面积 } if(area == sum) puts("Good"); else puts("Bad"); } return 0; }
View Code
相关文章推荐
- ZOJ 1292 Integer Inquiry
- CSUOJ 1226: ACM小组的内战
- csu 1054 约瑟夫环
- TLE:csu 1016 最小公倍数
- csu-1079
- CSU 1027 Smallbox魔方
- HDU1292 "下沙野骆驼"ACM夏令营
- CSU 1487 未覆盖顶点数量
- csuoj 1334: 好老师
- CSU 1317 Find the max Link
- csu 10月 月赛 F 题 ZZY and his little friends
- CSU 1116 Kingdoms
- 2014_csu选拔1_B
- CSU 1425 NUDT校赛 I题 Prime Summation
- csu 1459: Chess (橡棋)
- csu1160
- CSUOJ 1259 跳跳
- CSU-ACM2014年校队选拔赛指导赛解题报告
- CSU-1407: 最短距离
- CSU