POJ 1436 Horizontally Visible Segments(线段树)
2012-08-24 17:17
375 查看
转载请注明出处,谢谢/article/2566293.html
by---cxlove
题目:给出一些垂直的线段,两两可见的三条线段有多少组。
可见是说找出一条水平线段连接两条线段,而且这条线段不和别的线段相交。
http://poj.org/problem?id=1436
被yobobobo问起,竟然线段树没有做
将所有线段按X坐标排序,依次将线段插入
在插入之前先做一次查询,看线段所在的区间中有哪些线段可见。
典型的区间染色问题。
由于这里是线段,区间的端点是包括的,所以要把区间乘以2
相当于线段树中的(2*i,2*i)表示的是i这个点,而(2*i+1,2*i+1)表示的是(i,i+1)这个开区间
打一个邻接表,然后4层循环暴力
by---cxlove
题目:给出一些垂直的线段,两两可见的三条线段有多少组。
可见是说找出一条水平线段连接两条线段,而且这条线段不和别的线段相交。
http://poj.org/problem?id=1436
被yobobobo问起,竟然线段树没有做
将所有线段按X坐标排序,依次将线段插入
在插入之前先做一次查询,看线段所在的区间中有哪些线段可见。
典型的区间染色问题。
由于这里是线段,区间的端点是包括的,所以要把区间乘以2
相当于线段树中的(2*i,2*i)表示的是i这个点,而(2*i+1,2*i+1)表示的是(i,i+1)这个开区间
打一个邻接表,然后4层循环暴力
#include<iostream> #include<fstream> #include<iomanip> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cmath> #include<set> #include<map> #include<queue> #include<stack> #include<string> #include<vector> #include<ctime> #include<sstream> #include<cassert> #define LL long long #define eps 1e-7 #define zero(a) fabs(a)<eps #define inf 1<<30 #define N 8005 #define pi acos(-1.0) #define pb(a) push_back(a) #define lson step<<1 #define rson step<<1|1 using namespace std; struct SegmentTree{ int left,right,mid; int col; }L[N*2*4]; struct Node{ int x,y1,y2; }a[8005]; vector<int>v[8005]; bool cmp(Node n1,Node n2){ return n1.x<n2.x; } void Push_Down(int step){ if(L[step].col!=-1){ L[lson].col=L[rson].col=L[step].col; L[step].col=-1; } } void Bulid(int step,int l,int r){ L[step].left=l; L[step].right=r; L[step].mid=(l+r)/2; L[step].col=0; if(l==r) return; Bulid(lson,l,L[step].mid); Bulid(rson,L[step].mid+1,r); } void Update(int step,int l,int r,int c){ if(l==L[step].left&&r==L[step].right){ L[step].col=c; return; } Push_Down(step); if(r<=L[step].mid) Update(lson,l,r,c); else if(l>L[step].mid) Update(rson,l,r,c); else{Update(lson,l,L[step].mid,c);Update(rson,L[step].mid+1,r,c);} } bool flag[8005]; void Query(int step,int l,int r,int c){ if(L[step].col!=-1){ if(L[step].col&&!flag[L[step].col]) v[c].pb(L[step].col); flag[L[step].col]=true; return ; } Push_Down(step); if(r<=L[step].mid) Query(lson,l,r,c); else if(l>L[step].mid) Query(rson,l,r,c); else{Query(lson,l,L[step].mid,c);Query(rson,L[step].mid+1,r,c);} } int main(){ int t,n; scanf("%d",&t); while(t--){ int m=0; scanf("%d",&n); for(int i=1;i<=n;i++){ v[i].clear(); scanf("%d%d%d",&a[i].y1,&a[i].y2,&a[i].x); m=max(m,a[i].y2); } sort(a+1,a+1+n,cmp); Bulid(1,0,2*m); for(int i=1;i<=n;i++){ memset(flag,false,sizeof(flag)); Query(1,2*a[i].y1,2*a[i].y2,i); Update(1,2*a[i].y1,2*a[i].y2,i); } int ans=0; for(int i=1;i<=n;i++){ for(int j=0;j<v[i].size();j++){ for(int k=0;k<v[v[i][j]].size();k++) for(int r=0;r<v[i].size();r++) if(v[i][r]==v[v[i][j]][k]) ans++; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- poj 1436 Horizontally Visible Segments(线段树成段覆盖问题+简单hash),好题,覆盖问题想法较难
- poj 1436 Horizontally Visible Segments(线段树)
- POJ 1436 (线段树 区间染色) Horizontally Visible Segments
- POJ 1436 Horizontally VisibleSegments(线段树:区间覆盖染色)
- (中等) POJ 1436 Horizontally Visible Segments , 线段树+区间更新。
- poj 1436 Horizontally Visible Segments - 线段树区间更新
- poj 1436 Horizontally Visible Segments 线段树求垂直三角形的个数
- poj 1436 Horizontally Visible Segments(线段树基础,区间染色,拆点)
- POJ 1436 Horizontally Visible Segments(线段树区间染色查询)
- POJ 题目1436 Horizontally Visible Segments(线段树染色覆盖求相互是否可见)
- POJ 1436 Horizontally Visible Segments(线段树)
- POJ 1436 Horizontally Visible Segments(线段树区间修改)
- POJ 1436 Horizontally Visible Segments(线段树区间染色问题)
- [poj 1436]Horizontally Visible Segments[线段树]
- poj1436 Horizontally Visible Segments 线段树成段更新
- POJ 1436 Horizontally Visible Segments (线段树水过)
- POJ 1436——Horizontally Visible Segments(线段树,区间染色+暴力+简单hash)
- poj 1436 Horizontally Visible Segments(线段树)(第二部分成段更新 不需要延迟标记 )
- poj 1436 Horizontally Visible Segments(线段树、区间覆盖)
- POJ 1436 Horizontally Visible Segments(线段树)