水博客,水一水。
Horizontally Visible SegmentsTime Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 6290 | Accepted: 2287 |
Description
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
题意:输入n表示有n条线段,n行每行输入y1,y2,x表示线段的下端点,上端点以及线段的位置(横坐标位置),对于第i条线段和第k条线段如果用一条平行线能够经过它们并且在它们之间不经过其他线段,则称这两条线段互为可见,求有多少3条线段两两可见(懒得写题意,直接贴的别人的)
代码:
1 //线段树区间更新,端点放大2倍 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<cstdlib> 8 using namespace std; 9 typedef long long ll; 10 const int maxn=8e3+10; 11 12 #define lson l,m,rt<<1 13 #define rson m+1,r,rt<<1|1 14 15 int col[maxn<<2]; 16 bool mp[maxn][maxn]; 17 18 struct node{ 19 int y1,y2,x,id; 20 }line[maxn]; 21 22 bool cmp(node a,node b) 23 { 24 return a.x<b.x; 25 } 26 27 void init() 28 { 29 memset(mp,0,sizeof mp); 30 memset(line,0,sizeof line); 31 memset(col,0,sizeof col); 32 } 33 34 void pushdown(int rt) 35 { 36 if(col[rt]){ 37 col[rt<<1]=col[rt<<1|1]=col[rt]; 38 col[rt]=0; 39 } 40 } 41 42 void update(int L,int R,int c,int l,int r,int rt) 43 { 44 if(L<=l&&r<=R){ 45 col[rt]=c; 46 return ; 47 } 48 49 pushdown(rt); 50 int m=(l+r)>>1; 51 if(L<=m) update(L,R,c,lson); 52 if(R> m) update(L,R,c,rson); 53 } 54 55 void query(int L,int R,int c,int l,int r,int rt) 56 { 57 if(col[rt]){ 58 mp[c][col[rt]]=1; 59 return ; 60 } 61 62 if(l==r){ 63 return ; 64 } 65 66 int m=(l+r)>>1; 67 if(L<=m) query(L,R,c,lson); 68 if(R> m) query(L,R,c,rson); 69 } 70 71 int main() 72 { 73 int t; 74 scanf("%d",&t); 75 while(t--){ 76 init(); 77 int n; 78 scanf("%d",&n); 79 int N=-1; 80 for(int i=1;i<=n;i++){ 81 scanf("%d%d%d",&line[i].y1,&line[i].y2,&line[i].x); 82 line[i].id=i;line[i].y1*=2;line[i].y2*=2;N=max(N,max(line[i].y1,line[i].y2)); 83 } 84 sort(line+1,line+1+n,cmp);//按x轴从小到大排序,降维,只对y轴进行建树 85 for(int i=1;i<=n;i++){ 86 query(line[i].y1,line[i].y2,line[i].id,0,N,1); 87 update(line[i].y1,line[i].y2,line[i].id,0,N,1); 88 } 89 int ans=0; 90 for(int i=1;i<=n;i++){ 91 for(int j=1;j<=n;j++){ 92 if(mp[i][j]){ 93 for(int k=1;k<=n;k++){ 94 if(mp[i][k]&&mp[k][j]) ans++; 95 } 96 } 97 } 98 } 99 printf("%d\n",ans); 100 } 101 }