POJ 题目1436 Horizontally Visible Segments(线段树染色覆盖求相互是否可见)

来源:互联网 发布:c语言从右至左的运算符 编辑:程序博客网 时间:2024/04/30 03:16
Horizontally Visible Segments
Time Limit: 5000MS Memory Limit: 65536KTotal Submissions: 4715 Accepted: 1729

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

150 4 40 3 13 4 20 2 20 2 3

Sample Output

1

Source

Central Europe 2001

题目大意:给你一堆平行于y轴的线段,输入线段包含三个参数,y的起始坐标,y的终止坐标,和x坐标,两个线段可见,就是两个线段之间可以用一根水平的直线连起来,而且不会和其他的线相交,问有多少组三个线段两个可见

思路:需要注意的是输入的时候都是整数,但是水平线段经过的未必是整数,例如线段 1 2 和线段 3 4之间可以2和3的空隙中可以过线,把所有线段的长度都增加一倍来解决这个问题,把所有的线段按从左到右排序,相见是相互,然后从左向右扫,看左边能见几条,然后覆盖更新,最后用4重for循环,,暴力一下找ans=_=

ac代码

Problem: 1436  User: kxh1995 Memory: 1100K  Time: 172MS Language: C++  Result: Accepted 

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<vector>#include<iostream>using namespace std;#define maxn 8080<<1vector<int>vt[maxn];struct ss{int s,t,x;}b[maxn];int node[maxn<<2],vis[maxn];void init(int n){int i;for(i=0;i<=n;i++){vt[i].clear();vis[i]=0;}}int cmp(const void *a,const void *b){return (*(struct ss *)a).x-(*(struct ss *)b).x;}void build(int l,int r,int tr){node[tr]=-1;if(l==r)return;int mid=(l+r)>>1;build(l,mid,tr<<1);build(mid+1,r,tr<<1|1);}void pushdown(int tr){if(node[tr]!=-1){node[tr<<1]=node[tr<<1|1]=node[tr];node[tr]=-1;}}void update(int L,int R,int val,int l,int r,int tr){if(l==L&&r==R){node[tr]=val;return;}pushdown(tr);int mid=(l+r)>>1;if(R<=mid)update(L,R,val,l,mid,tr<<1);elseif(L>mid)update(L,R,val,mid+1,r,tr<<1|1);else{update(L,mid,val,l,mid,tr<<1);update(mid+1,R,val,mid+1,r,tr<<1|1);}}void query(int L,int R,int val,int l,int r,int tr){if(node[tr]!=-1){if(vis[node[tr]]!=val){vt[node[tr]].push_back(val);vis[node[tr]]=val;}return;}if(l==r)return;pushdown(tr);int mid=(l+r)>>1;if(L<=mid)query(L,R,val,l,mid,tr<<1);if(R>mid)query(L,R,val,mid+1,r,tr<<1|1);}int main(){int t;scanf("%d",&t);while(t--){int n,i;scanf("%d",&n);init(n);for(i=0;i<n;i++){scanf("%d%d%d",&b[i].s,&b[i].t,&b[i].x);b[i].s<<=1;b[i].t<<=1;}qsort(b,n,sizeof(b[0]),cmp);build(0,maxn,1);for(i=0;i<n;i++){query(b[i].s,b[i].t,i,0,maxn,1);update(b[i].s,b[i].t,i,0,maxn,1);}int ans=0;int j,x,y;for(i=0;i<n;i++){int num=vt[i].size();for(j=0;j<num;j++){int v=vt[i][j];for(x=j+1;x<num;x++){int num2=vt[v].size();for(y=0;y<num2;y++){if(vt[i][x]==vt[v][y])ans++;}}}}printf("%d\n",ans);}}


0 0