POJ1436:Horizontally Visible Segments(区间更新)

来源:互联网 发布:忍者村大战2 知乎 编辑:程序博客网 时间:2024/06/08 07:14

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
 
题意:每条线段的x轴是固定的,还有就是线段的两个端点的y坐标,要求出三个线段两两可见的一共有几对
思路:为了方便处理,要将y坐标*2来处理
 
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int L = 8000+10;int color[L<<3];bool map[L][L];//一开始我存的int型,但是int型会超内存,用bool型能节省大量空间int n;struct node{    int l,r,n;} a[L<<3];struct kode{    int x,y1,y2;} s[L];int cmp(kode a,kode b){    return a.x<b.x;}void init(int l,int r,int i){    a[i].l = l;    a[i].r = r;    a[i].n = 0;    if(l==r)        return;    int mid = (l+r)>>1;    init(l,mid,2*i);    init(mid+1,r,2*i+1);}void insert(int l,int r,int i,int m){    if(l<=a[i].l && a[i].r<=r)    {        a[i].n = m;        return ;    }    if(a[i].n!=-1)//将父亲节点的状态更新到孩子节点中    {        a[2*i].n = a[2*i+1].n = a[i].n;        a[i].n = -1;    }    if(l<=a[2*i].r)        insert(l,r,2*i,m);    if(r>=a[2*i+1].l)        insert(l,r,2*i+1,m);}void query(int l,int r,int i,int m){    if(a[i].n!=-1)    {        map[a[i].n][m] = true;        return ;    }    if(a[i].l == a[i].r)        return;    if(a[i].n!=-1)    {        a[2*i].n = a[2*i+1].n = a[i].n;        a[i].n = -1;    }    if(l<=a[2*i].r)        query(l,r,2*i,m);    if(r>=a[2*i+1].l)        query(l,r,2*i+1,m);}int main(){    int t,ans,i,x,y1,y2,j,k;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i = 1; i<=n; i++)        {            scanf("%d%d%d",&s[i].y1,&s[i].y2,&s[i].x);            s[i].y1*=2;            s[i].y2*=2;;        }        sort(s+1,s+1+n,cmp);        memset(map,false,sizeof(map));        init(0,16000,1);        for(i = 1; i<=n; i++)        {            query(s[i].y1,s[i].y2,1,i);            insert(s[i].y1,s[i].y2,1,i);        }        ans = 0;        for(i = 1; i<=n; i++)//暴力求解            for(j = 1; j<=n; j++)                if(map[i][j])                {                    for(k = 1; k<=n; k++)                        if(map[i][k] && map[j][k])                            ans++;                }        printf("%d\n",ans);    }    return 0;}

原创粉丝点击