POJ-1436 线段树 区间更新
2012-03-08 16:24
323 查看
题中定义了什么叫做可见线段。所谓可见线段就是在给定的垂直与x轴的直线中,能够在两个直线之间连接一条平行线,并且这条平行线不与任何其他的直线相交。
WA一次,就是因为没有考虑到在建立点树的过程中会出现将 [1, 2] 和 [3, 4] 视为一条连接的直线,所以最后给坐标乘以一个2.
代码如下:
WA一次,就是因为没有考虑到在建立点树的过程中会出现将 [1, 2] 和 [3, 4] 视为一条连接的直线,所以最后给坐标乘以一个2.
代码如下:
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> #include <map> #define MAXN 8000 using namespace std; struct Seq { int y1, y2, x; bool operator < (Seq t) const { return x < t.x; } }e[MAXN+5]; struct { int l, r, who; }seg[MAXN*8]; map<int,int>m[MAXN+5]; void build(int f, int l, int r) { int mid = l+r >> 1; seg[f].l = l, seg[f].r = r; seg[f].who = 0; if (r > l) { build(f<<1, l, mid); build(f<<1|1, mid+1, r); } } void up(int f) { if (seg[f<<1].who == seg[f<<1|1].who) seg[f].who = seg[f<<1].who; else seg[f].who = -1; } void modify(int f, int l, int r, int who, map<int, int>*m) { int mid = seg[f].l+seg[f].r >> 1; if (seg[f].l == l && seg[f].r == r && (seg[f].who != -1 || r==l)) { if (seg[f].who != -1 && seg[f].who != 0) m[who][seg[f].who] = 1; seg[f].who = who; } else if (seg[f].r > seg[f].l) { if (seg[f].who == 0) { seg[f<<1].who = seg[f<<1|1].who = seg[f].who; seg[f].who = -1; } else if (seg[f].who != -1) { m[who][seg[f].who] = 1; seg[f<<1].who = seg[f<<1|1].who = seg[f].who; seg[f].who = -1; } if (r <= mid) modify(f<<1, l, r, who, m); else if (l > mid) modify(f<<1|1, l, r, who, m); else { modify(f<<1, l, mid, who, m); modify(f<<1|1, mid+1, r, who, m); } up(f); } } int main() { map<int,int>::iterator it1, it2; int T, M, y1, y2, x, ans; scanf("%d", &T); build(1, 0, 2*MAXN); while (T--) { ans = 0; seg[1].who = 0; scanf("%d", &M); for (int i = 1; i <= M; ++i) { scanf("%d %d %d", &e[i].y1, &e[i].y2, &e[i].x); e[i].y1 <<= 1, e[i].y2 <<= 1; m[i].clear(); } sort(e+1, e+1+M); for (int i = 1; i <= M; ++i) { // printf("%d %d %d\n", e[i].y1, e[i].y2, e[i].x); modify(1, e[i].y1, e[i].y2, i, m); /* for (it = m[i].begin(); it != m[i].end(); ++it) printf(".. %d ", it->first); */ } for(int i = 1; i <= M; ++i) // 扫描整个表 { for(it1 = m[i].begin(); it1 != m[i].end(); ++it1) // 遍历第i条线的可见线段 { int k = it1->first; // 记录与其中的第k条线段可见 for(it2 = m[i].begin(); it2 != m[i].end(); ++it2) // 如果第k条线段与第i条线段有共同的可见线段的话 ans++ { if (m[k].count(it2->first)) ans++; } } } printf("%d\n",ans); } return 0; }
相关文章推荐
- poj 1436 Horizontally Visible Segments - 线段树区间更新
- (中等) POJ 1436 Horizontally Visible Segments , 线段树+区间更新。
- POJ 1436 Horizontally Visible Segments(线段树区间更新)
- POJ 1436 Horizontally Visible Segments [线段树-区间更新]【数据结构】
- 线段树区间更新——POJ 1436
- POJ - 3468 A Simple Problem with Integers(线段树区间更新,区间查询)
- POJ-3468-A Simple Problem with Integers(线段树区间更新)
- Poj 2528 Mayor's posters (线段树区间更新+离散化)
- poj 3468 A Simple Problem with Integers(线段树——区间更新)
- POJ 3225 Help with Intervals (线段树,区间更新)
- POJ 3468 (线段树,区间更新,查询区间)
- poj 3468 线段树(区间更新)模板题
- [poj 2528] Mayor's Posters[线段树][区间更新]
- poj 3468 A Simple Problem with Integers (线段树区间更新 + 树状数组区间更新)
- POJ1436:Horizontally Visible Segments(区间更新)
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
- poj 2892 Tunnel Warfare(线段树 单点更新 区间合并)
- poj 2777 Count Color(线段树区间更新+位运算)
- POJ 2777 Count Color 线段树区间更新位运算
- A Simple Problem with Integers - POJ 3468 - 线段树 区间更新