POJ 1436 Horizontally Visible Segments [线段树-区间更新]【数
题目链接:http://poj.org/problem?id=1436 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. 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. 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. 1 1 Central Europe 2001 解题思路: ※数据不保证一定是从左到右的 一定要排序啊. //#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <vector>
#include <map>
#include <queue>
using namespace std;
#define INF (~(1<<31))
#define INFLL (~(1ll<<63))
#define pb push_back
#define mp make_pair
#define abs(a) ((a)>0?(a):-(a))
#define lalal puts("*******");
#define s1(x) scanf("%d",&x)
#define Rep(a,b,c) for(int a=(b);a<=(c);a++)
typedef long long int LL ;
typedef unsigned long long int uLL ;
const int MOD = 1e9+7;
const int N = 8000+5;
const double eps = 1e-6;
const double PI = acos(-1.0);
/***********************************************************************/
bool path[N][N];
struct node {
int l,r;
int val;
int md() {return (l+r)>>1;}
int len(){return (r-l+1);}
}tree[N<<3];
#define ll (rt<<1)
#define rr (rt<<1|1)
#define mid (tree[rt].md())
void build(int rt,int l,int r)
{
tree[rt].l=l,tree[rt].r=r,tree[rt].val=0;
if(l==r) return ;
build(ll,l,mid);
build(rr,mid+1,r);
}
void pushdown(int rt)
{
if(tree[rt].val)
{
tree[ll].val = tree[rr].val = tree[rt].val;
tree[rt].val =0;
}
}
void update(int rt,int &L,int &R,int &val)
{
if(L<=tree[rt].l&&tree[rt].r<=R){tree[rt].val=val;return ;}
pushdown(rt);
if(L<=mid) update(ll,L,R,val);
if(R> mid) update(rr,val);
return ;
}
void query(int rt,int &id)
{
if(tree[rt].val){path[id][tree[rt].val]=true; return ;}
if(tree[rt].l==tree[rt].r) return ;
if(L<=mid) query(ll,id);
if(R> mid) query(rr,id);
return ;
}
struct segment{
int y1,y2,x1;
}e[N];
bool cmp (segment A,segment B)
{
return A.x1<B.x1;
}
int main()
{
int _;
while(~s1(_))
{
while(_--)
{
int n;
s1(n);
memset(path,0,sizeof(path));
build(1,8000*2);
int y1,x1;
Rep(i,1,n)
{
s1(y1),s1(y2),s1(x1);
e[i].y1=(y1<<1);
e[i].y2=(y2<<1);
e[i].x1=x1;
}
sort(e+1,e+n+1,cmp);
Rep(i,n)
{
query (1,e[i].y1,e[i].y2,i);
update(1,i);
}
LL sum = 0;
Rep(i,n)Rep(j,n)
if(path[i][j])
Rep(k,n)if(path[i][k]&&path[k][j]) sum++;
printf("%dn",sum); //因为只存了单向边 所以就不用去重了
}
}
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |