• 【POJ1436】Horizontally Visible Segments-线段树区间更新


    (本人本题完成于2016-7-19)
    题目大意:给N条垂直于x轴的线段,当两条线段之间可以连一条水平线并且这条水平线不和别的任意垂直线段相交,则称这两条线段是可见的,求满足两两可见的三条线段有多少对。
    做法:先将这N条线段以x坐标从小到大排序,再逐一进行下列操作:1.询问该线段的y坐标区间,记录该线段与之前线段之间的可见关系;2.将该线段插入线段树(区间更新)。
    注意到线段树是以整数坐标为单位的,这样就会使两条x坐标相等的线段之间有1个单位长度的空隙时,无法判断部分线段之间的可见关系,因此需将所有线段的y坐标*2来处理。
    以下是本人代码:
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    long d,n,a[8010]={0},b[8010]={0},x[8010]={0},ans;
    bool v[8010][8010]={0}; //这里用int会超内存,用bool可以省下大部分内存
    struct
    {
      long l,r; //区间的左右端点
      long n; //n表示(l,r)区间最后被第n条线段完全覆盖,n为0时表示不能确定
    }seg[50010]; //结构体定义线段树的节点
    
    void quicksort(long l,long r)
    {
      if (l>=r) return;
      long mid=x[(l+r)/2],i=l,j=r;
      while(i<=j)
      {
        while(x[i]<mid) i++;
    	while(x[j]>mid) j--;
    	if (i<=j)
    	{
    	  long temp;
    	  temp=a[i];a[i]=a[j];a[j]=temp;
    	  temp=b[i];b[i]=b[j];b[j]=temp;
    	  temp=x[i];x[i]=x[j];x[j]=temp;
    	  i++;j--;
    	}
      }
      quicksort(l,j);
      quicksort(i,r);
    }
    
    void buildtree(long no,long l,long r)
    {
      seg[no].l=l;seg[no].r=r;seg[no].n=0;
      if (l!=r)
      {
        long mid=(l+r)/2;
        buildtree(2*no,l,mid);
    	buildtree(2*no+1,mid+1,r);
      }
    }
    
    void insert(long no,long s,long t,long x)
    {
      if (seg[no].l>=s&&seg[no].r<=t) seg[no].n=x; //区间被完全覆盖,将seg[no].n更新为x
      else
      {
        long mid=(seg[no].l+seg[no].r)/2;
    	if (seg[no].n!=0)
    	{
    	  seg[2*no].n=seg[2*no+1].n=seg[no].n;
    	  seg[no].n=0;
    	} //将节点信息下放
    	if (s<=mid) insert(2*no,s,t,x);
    	if (t>mid) insert(2*no+1,s,t,x);
      }
    }
    
    void query(long no,long s,long t,long x)
    {
      if (seg[no].n!=0) v[seg[no].n][x]=true; //标记第seg[no].n条线段和第x条线段之间的可见关系
      else
      {
        if (seg[no].l!=seg[no].r)
    	{
    	  if (seg[no].n!=0)
    	  {
    	    seg[2*no].n=seg[2*no+1].n=seg[no].n;
      	    seg[no].n=0;
    	  }
    	  long mid=(seg[no].l+seg[no].r)/2;
    	  if (s<=mid) query(2*no,s,t,x);
    	  if (t>mid) query(2*no+1,s,t,x);
    	}
      }
    }
    
    int main()
    {
      scanf("%ld",&d);
      for(int t=1;t<=d;t++)
      {
        buildtree(1,0,16000);
    	scanf("%ld",&n);
    	for(int i=1;i<=n;i++)
    	{
    	  scanf("%ld %ld %ld",&a[i],&b[i],&x[i]);
    	  a[i]*=2;b[i]*=2;
    	}
    	quicksort(1,n);
    	memset(v,0,sizeof(v));
    	for(int i=1;i<=n;i++)
    	{
    	  query(1,a[i],b[i],i);
    	  insert(1,a[i],b[i],i);
    	}
    	ans=0;
    	for(int i=1;i<=n;i++)
    	  for(int j=i+1;j<=n;j++)
    	    if (v[i][j])
    		{
    		  for(int k=i;k<=j;k++)
    		    if (v[i][k]&&v[k][j]) ans++;
    		} //统计满足条件的线段对
    	printf("%ld
    ",ans);
      }
      
      return 0;
    }
  • 相关阅读:
    一个通过JSONP跨域调用WCF REST服务的例子(以jQuery为例)
    步步为营UML建模系列七、表图(Data model diagram)
    步步为营UML建模系列六、类图(Class diagram)
    WebEx
    使用Nancy和Simple.Data两个轻量级的框架打造一个分布式开发系统
    细说 ASP.NET控制HTTP缓存
    WCSF vs ASP.NET MVC
    使用KTM(内核事务管理器)进行文件事务处理
    .net 2.0下的OOXML神器:NPOI.OpenXml4Net
    为什么System.Attribute的GetHashCode方法需要如此设计?
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9794028.html
Copyright © 2020-2023  润新知