您的位置:首页 > 其它

(线段树)poj1436-Horizontally Visible Segments

2017-02-21 18:13 465 查看
There is a number of disjoint vertical line segments in the plane. We say that two segments are horizontally visible if they can be connected by a horizontal line segment that does not have any common points with other vertical segments. Three different vertical segments are said to form a triangle of segments if each two of them are horizontally visible. How many triangles can be found in a given set of vertical segments?

Task

Write a program which for each data set:

reads the description of a set of vertical segments,

computes the number of triangles in this set,

writes the result.

Input

The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 20. The data sets follow.

The first line of each data set contains exactly one integer n, 1 <= n <= 8 000, equal to the number of vertical line segments.

Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces:

yi', yi'', xi - y-coordinate of the beginning of a segment, y-coordinate of its end and its x-coordinate, respectively. The coordinates satisfy 0 <= yi' < yi'' <= 8 000, 0 <= xi <= 8 000. The segments are disjoint.

Output

The output should consist of exactly d lines, one line for each data set. Line i should contain exactly one integer equal to the number of triangles in the i-th data set.

Sample Input

1
5
0 4 4
0 3 1
3 4 2
0 2 2
0 2 3

Sample Output

1

就是区间染色问题。用线段树维护每个区间的颜色,对于读入数据处理排序为从左到右update,x坐标其实无关紧要。用二维bool数组记录两个线段是否水平可视,枚举即可求得答案。


1 #include <iostream>
2 //#include<bits/stdc++.h>
3 #include <stack>
4 #include <queue>
5 #include <map>
6 #include <set>
7 #include <cstdio>
8 #include <cstring>
9 #include <algorithm>
10 using namespace std;
11 typedef long long ll;
12 typedef unsigned long long ull;
13 const int MAX=16000;
14 int d,n;
15 bool link[8001][8001];
16 struct node
17 {
18     int col;
19 }st[20*MAX];
20 void init(int l,int r,int k)
21 {
22     st[k].col=0;
23     if(l==r)
24         return;
25     init(l,(l+r)/2,2*k);
26     init((l+r)/2+1,r,2*k+1);
27 }
28 void pushdown(int k)
29 {
30     if(st[k].col==0)
31         return;
32     st[2*k].col=st[2*k+1].col=st[k].col;
33     st[k].col=0;
34 }
35 void update(int l,int r,int L,int R,int k,int j)//[l,r]是目标区间 [L,R]是当前区间,j是向左看的线的编号
36 {
37     if(L>=l&&R<=r)
38     {
39         st[k].col=j;
40         return;
41     }
42     if(L==R)
43         return;
44     pushdown(k);
45     if(l<=(L+R)/2)
46         update(l,r,L,(L+R)/2,2*k,j);
47     if(r>(L+R)/2)
48         update(l,r,(L+R)/2+1,R,2*k+1,j);
49 }
50 void query(int l,int r,int L,int R,int k,int j)//[L,R]是当前区间,[l,r]是目标区间
51 {
52     if(st[k].col)
53     {
54         link[st[k].col][j]=true;
55         return;
56     }
57     if(L==R)
58         return;
59     if(l<=(L+R)/2)
60         query(l,r,L,(L+R)/2,2*k,j);
61     if(r>(R+L)/2)
62         query(l,r,(L+R)/2+1,R,2*k+1,j);
63 }
64 struct re
65 {
66     int x,xia,shang;
67 }z[MAX];
68 bool cmp(re aa,re bb)
69 {
70     if(aa.x!=bb.x)
71     return aa.x<bb.x;
72     else
73         return aa.xia<bb.xia;
74 }
75 int main()
76 {
77     scanf("%d",&d);
78     int x,s,i,tem;
79     while(d--)
80     {
81         scanf("%d",&n);
82         init(0,MAX,1);
83         memset(link,false,sizeof(link));
84 //        for(i=1;i<=n;i++)
85 //        {
86 //            scanf("%d %d %d",&x[i],&s,&tem);
87 //            update(2*x,2*s,0,MAX,1,i);
88 //        }
89         for(i=1;i<=n;i++)
90             scanf("%d %d %d",&z[i].xia,&z[i].shang,&z[i].x);
91         sort(z+1,z+n+1,cmp);
92         for(i=1;i<=n;i++)
93             {
94                 query(2*z[i].xia,2*z[i].shang,0,MAX,1,i);
95                 update(2*z[i].xia,2*z[i].shang,0,MAX,1,i);
96
97             }
98         int j,k,q;
99         int an=0;
100         for(i=1;i<=n;i++)
101         {
102             for(j=i+1;j<=n;j++)
103             {
104                 if(link[i][j])
105                 {
106 //                    printf("%d %d i:%d %d %d j:%d %d %d\n",i,j,2*z[i].xia,2*z[i].shang,z[i].x,2*z[j].xia,2*z[j].shang,z[j].x);
107                     for(q=i+1;q<j;q++)
108                     {
109                         if(link[i][q]&&link[q][j])
110                             an++;
111                     }
112                 }
113             }
114         }
115         printf("%d\n",an);
116     }
117 }



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: