(线段树)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
Sample Output
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 }
相关文章推荐
- poj 1436 Horizontally Visible Segments(线段树基础,区间染色,拆点)
- poj 1436 线段树 Horizontally Visible Segments
- POJ 1436——Horizontally Visible Segments(线段树,区间染色+暴力+简单hash)
- poj1436 Horizontally Visible Segments 线段树成段更新
- POJ 1436 Horizontally Visible Segments 线段树 成段更新
- POJ 题目1436 Horizontally Visible Segments(线段树染色覆盖求相互是否可见)
- poj 1436 Horizontally Visible Segments[线段树]
- POJ 1436 Horizontally Visible Segments(线段树区间染色问题)
- poj 1436 Horizontally Visible Segments(线段树)
- POJ 1436 Horizontally Visible Segments (线段树+区间覆盖)
- poj 1436 Horizontally Visible Segments(线段树 区间的覆盖关系)
- POJ 1436 Horizontally Visible Segments (线段树水过)
- poj 1436 Horizontally Visible Segments(线段树、区间覆盖)
- poj 1436 线段树区间操作 Horizontally Visible Segments
- POJ 1436 Horizontally Visible Segments(线段树)
- POJ 1436 Horizontally Visible Segments(线段树区间修改)
- POJ 1436 Horizontally Visible Segments 线段树 染色
- poj 1436 Horizontally Visible Segments 线段树求垂直三角形的个数
- poj 1436 Horizontally Visible Segments - 线段树区间更新
- POJ 1436 Horizontally VisibleSegments(线段树:区间覆盖染色)