Horizontally Visible Segments
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 4507   Accepted: 1662

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

Source

 
 
题目意思:
给n条垂直x轴的线段,若两个线段之间存在没有其他线段挡着的地方,则称两个线段为可见的。若3条线段两两互为可见,称为一组,求n条线段中有多少组。
 
 
思路:
很明显线段树,按x坐标排序,以y建线段树,每加入一条边就和之前的颜色用visited标记起来,然后暴力三重循环即可(虽然一重循环是8000,但是实际上没这么多)。
注意,插入边的时候,边的两端点*2再插入,还是边界问题。
 
代码:
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 10005
#define ll root<<1
#define rr root<<1|1
#define mid (a[root].l+a[root].r)/2 int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int abs(int x,int y){return x<?-x:x;} struct Line{
int y1, y2, x;
}line[N]; struct node{
int l, r, val;
bool f;
}a[N*]; int n;
bool visited[][]; bool cmp(Line a,Line b){
return a.x<b.x;
} void build(int l,int r,int root){
a[root].l=l;
a[root].r=r;
a[root].val=;
a[root].f=false;
if(l==r) return;
build(l,mid,ll);
build(mid+,r,rr);
} void down(int root){
if(a[root].f&&a[root].val>&&a[root].l!=a[root].r){
a[ll].val=a[rr].val=a[root].val;
a[root].val=-;
a[ll].f=a[rr].f=true;
}
}
void update(int l,int r,int val,int root){
//if(!a[root].f) a[root].f=true;
if(a[root].val==val) return;
if(a[root].l==l&&a[root].r==r){
if(!a[root].f){
a[root].f=true;
a[root].val=val;
return;
}
else{
if(a[root].val>){
if(!visited[a[root].val][val]){
visited[a[root].val][val]=visited[val][a[root].val]=true;
}
a[root].val=val;
return;
}
}
}
down(root);
if(r<=a[ll].r) update(l,r,val,ll);
else if(l>=a[rr].l) update(l,r,val,rr);
else{
update(l,mid,val,ll);
update(mid+,r,val,rr);
}
if(a[ll].f||a[rr].f) a[root].f=true;
if(a[ll].val==a[rr].val&&a[ll].val>) a[root].val=a[ll].val;
} void out(int root){
if(a[root].l==a[root].r) {
printf("%d ",a[root].val);return;
}
down(root);
out(ll);
out(rr);
}
main()
{
int t, i, j, k;
cin>>t;
while(t--){
scanf("%d",&n);
int minh=, maxh=-;
for(i=;i<n;i++){
scanf("%d %d %d",&line[i].y1,&line[i].y2,&line[i].x);
minh=min(min(line[i].y1,line[i].y2),minh);
maxh=max(max(line[i].y1,line[i].y2),maxh);
}
build(minh*,maxh*,);
sort(line,line+n,cmp);
memset(visited,false,sizeof(visited));
for(i=;i<n;i++) update(line[i].y1*,line[i].y2*,i+,);//,out(1),cout<<endl;
int ans=; for(i=;i<=n;i++){
for(j=i+;j<=n;j++){
if(visited[i][j]){
for(k=j+;k<=n;k++){
if(visited[j][k]&&visited[i][k]){
ans++;
}
}
}
}
}
printf("%d\n",ans); }
}

POJ 1436 区间染色的更多相关文章

  1. POJ 2528 区间染色,求染色数目,离散化

    Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 47905   Accepted: 13903 ...

  2. POJ 1436 (线段树 区间染色) Horizontally Visible Segments

    这道题做了快两天了.首先就是按照这些竖直线段的横坐标进行从左到右排序. 将线段的端点投影到y轴上,线段树所维护的信息就是y轴区间内被哪条线段所覆盖. 对于一条线段来说,先查询和它能相连的所有线段,并加 ...

  3. POJ 2777.Count Color-线段树(区间染色+区间查询颜色数量二进制状态压缩)-若干年之前的一道题目。。。

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 53312   Accepted: 16050 Des ...

  4. POJ 3657 Haybale Guessing(区间染色 并查集)

    Haybale Guessing Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2384   Accepted: 645 D ...

  5. POJ 1436 Horizontally Visible Segments(线段树)

    POJ 1436 Horizontally Visible Segments 题目链接 线段树处理染色问题,把线段排序.从左往右扫描处理出每一个线段能看到的右边的线段,然后利用bitset维护枚举两个 ...

  6. Mayor's posters-POJ2528 区间染色+离散化

    题意: 在一面长度为10000000 的墙上贴广告,告诉你每张海报的l,r(1 <= li <= ri <= 10000000.),让你求最后有几张海报露出来 链接:http://p ...

  7. 线段树(区间树)之区间染色和4n推导过程

    前言 线段树(区间树)是什么呢?有了二叉树.二分搜索树,线段树又是干什么的呢?最经典的线段树问题:区间染色:正如它的名字而言,主要解决区间的问题 一.线段树说明 1.什么是线段树? 线段树首先是二叉树 ...

  8. POJ-2777 Count Color(线段树,区间染色问题)

    Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 40510 Accepted: 12215 Descrip ...

  9. HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)

    题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工 ...

随机推荐

  1. Python学习(16)File(文件)方法

    Python File(文件) 方法 file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读 ...

  2. Python学习(5)条件语句

    目录 Python 条件语句 Python 简单的语句组 Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了 ...

  3. HTML字符实体

    常用实体符号:

  4. 算法_栈与队列的Java链表实现

    链表是一个递归的数据结构,它或者为null,或者是指向一个结点的引用,该结点含有一个泛型的元素和指向另一个链表的引用.可以用一个内部类来定义节点的抽象数据类型: private class Node ...

  5. 【Todo】OSGi学习

    经常听到.见到OSGi这个名字.那么就单开一篇文章记录一下对OSGi的学习吧. 主要是做一些概念上面的学习.暂时不打算深入实践. 主要参考:http://www.osgi.com.cn/article ...

  6. iOS项目中的version和build

    Version在plist文件中的key是“CFBundleShortVersionString”,标识应用程序的发布版本号,和AppStore上的版本号保持一致.该版本的版本号是三个分隔的整数组成的 ...

  7. Codeforces 527C Glass Carving

    vjudge 上题目链接:Glass Carving 题目大意: 一块 w * h 的玻璃,对其进行 n 次切割,每次切割都是垂直或者水平的,输出每次切割后最大单块玻璃的面积: 用两个 set 存储每 ...

  8. [css] 【转载】 精简高效的CSS命名准则/方法

    原文链接:http://www.zhangxinxu.com/wordpress/2010/09/%E7%B2%BE%E7%AE%80%E9%AB%98%E6%95%88%E7%9A%84css%E5 ...

  9. SqlServer_事务

    事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

  10. 转!!java中关键字volatile的作用

    用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对A的访问其实访问的是B.只在某些动作时才进行A和B的同步.因此存在A和B不一致的情况.volatile就是用来 ...