ZOJ 1391 Horizontally Visible Segments(线段树)

来源:互联网 发布:淘宝网纸箱 编辑:程序博客网 时间:2024/06/02 02:31

首先对线段按照x坐标排序,对于每一条线段的y坐标都乘以2,因为如果有两条同一x坐标的线段分别y坐标为1-2,3-4 2和3之间其实是可以通过的.如果不乘二就会被忽略掉了.

然后按顺序插入每一条线段,每条线段染一种颜色,对于后面插入的线段i首先查询下 [yi1,yi2]区间里的能看见的颜色,这些颜色的线段就可以看见线段i,然后把这些颜色的线段的vector里插入i.

因为里面有很多重复的数据,所以用一下unique.

最后枚举一下.

#include <iostream>#include <cstdio>#include <memory.h>#include <algorithm>#include <vector>using namespace std;#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const int maxn=17000;int segs[maxn*3], n, m;vector<int>vs[maxn/2];struct segment{int y1,y2,x;bool operator<(const segment & rhs)const{return x < rhs.x;}}ss[maxn/2];void build(int l,int r,int rt){segs[rt] = 0;if (l == r){return;}int m = (l + r) >> 1;build(lson), build(rson);}void query(int L, int R, int l, int r, int rt, int id){if (segs[rt]){vs[segs[rt]].push_back(id);return;}if(l == r) return;if(segs[rt]){segs[rt << 1] = segs[rt << 1 | 1] = segs[rt];segs[rt]=0;}int m = (l + r) >> 1;if(L <= m)query(L, R, lson, id);if(R > m)query(L, R, rson, id);}void update(int L, int R, int l, int r, int rt, int id){if (L <= l && r <= R){segs[rt] = id;return ;}int m = (l + r) >> 1;if(segs[rt]){segs[rt << 1] = segs[rt << 1 | 1] = segs[rt];segs[rt]=0;}if(L <= m)update(L, R, lson, id);if(R > m)update(L, R, rson, id);}int main(){int t;scanf("%d",&t);while (t--){scanf("%d",&n);int maxy=0;for (int i=1;i<=n;++i){scanf("%d%d%d", &ss[i].y1, &ss[i].y2, &ss[i].x);ss[i].y1 = (ss[i].y1 << 1) + 1;ss[i].y2 = (ss[i].y2 << 1) + 1;maxy = max(maxy, max(ss[i].y2, ss[i].y1));vs[i].clear();}build(1, maxy, 1);sort(ss + 1, ss + n + 1);for (int i = 1; i <= n; ++i){query(ss[i].y1, ss[i].y2, 1, maxy, 1, i);update(ss[i].y1, ss[i].y2, 1, maxy, 1, i);}int ans = 0;for (int i = 1 ; i <= n; ++i){vs[i].erase(unique(vs[i].begin(),vs[i].end()), vs[i].end());}for (int i = 1 ; i <= n; ++i){int si = vs[i].size();for (int j = 0; j < si; ++j){for (int k = j + 1; k < si; ++k){int sk = vs[vs[i][j]].size();for (int l = 0; l < sk; ++l){if (vs[vs[i][j]][l] == vs[i][k]){ans++;break;}}}}}printf("%d\n",ans) ;}return 0;}