zoukankan      html  css  js  c++  java
  • (中等) POJ 1436 Horizontally Visible Segments , 线段树+区间更新。

    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? 
     
      题意大致就是说给你一些线段,问相邻两个线段有没有公共的部分,且没有其他线段阻挡。
      
      首先对x排序,然后枚举,对于每个线段,先询问这个区间上的所有其他线段,然后再覆盖更新。
      对于COL数组,如果为-1表示这个区间上有多个线段,否则的话表示的是线段的编号(这里假设先放了一个编号为0的线段。)
      (PS:我能说这个题我调试了一下午吗,刚开始把COL设置为了bool的变量,结果。。。T T , 一直没找出错误来。。。痛苦。。。)
     
    代码如下:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    
    #define lson L,M,po*2
    #define rson M+1,R,po*2+1
    
    using namespace std;
    
    const int N=8000*2;
    
    int COL[8008*2*4];
    bool map1[8008][8008];
    
    void pushDown(int po)
    {
        if(COL[po]>=0)
        {
            COL[po*2]=COL[po*2+1]=COL[po];
            COL[po]=-1;
        }
    }
    
    void update(int ul,int ur,int ut,int L,int R,int po)
    {
        if(ul<=L&&ur>=R)
        {
            COL[po]=ut;
    
            return;
        }
    
        pushDown(po);
    
        int M=(L+R)/2;
    
        if(ul<=M)
            update(ul,ur,ut,lson);
        if(ur>M)
            update(ul,ur,ut,rson);
    
        if(COL[po*2]==COL[po*2+1])          //这里算是一个剪枝操作,可以减少递归次数。
            COL[po]=COL[po*2];
        else
            COL[po]=-1;
    }
    
    void query(int ql,int qr,int qt,int L,int R,int po)
    {
        if(COL[po]!=-1)
        {
            map1[qt][COL[po]]=map1[COL[po]][qt]=1;
            return;
        }
    
        if(L==R)
            return;
    
        int M=(L+R)/2;
    
        if(ql<=M)
            query(ql,qr,qt,lson);
        if(qr>M)
            query(ql,qr,qt,rson);
    }
    
    struct state
    {
        int y1,y2,x1;
    };
    
    state sta[8008];
    
    int cmp(const void*a,const void*b)
    {
        return (*(state*)a).x1-(*(state*)b).x1;
    }
    
    int main()
    {
        int d;
        cin>>d;
    
        int n;
    
        while(d--)
        {
            memset(map1,0,sizeof(map1));
            memset(COL,0,sizeof(COL));
    
            cin>>n;
    
            for(int i=0;i<n;++i)
                scanf("%d %d %d",&sta[i].y1,&sta[i].y2,&sta[i].x1);
    
            qsort(sta,n,sizeof(state),cmp);
    
            for(int i=1;i<=n;++i)
            {
                query(sta[i-1].y1*2,sta[i-1].y2*2,i,0,N,1);
                update(sta[i-1].y1*2,sta[i-1].y2*2,i,0,N,1);
            }
    
            long long ans=0;
    
            for(int i=1;i<=n;++i)           //直接暴力求解,居然不超时。。。
                for(int j=i+1;j<=n;++j)
                    if(map1[i][j])
                        for(int k=j+1;k<=n;++k)
                            if(map1[i][k]&&map1[j][k])
                                ++ans;
    
            cout<<ans<<endl;
        }
    
    
    
        return 0;
    }
    View Code
  • 相关阅读:
    app测试更多机型系统解决方法
    Dsyy的第一篇博文~
    linux服务器下安装node
    android UI进阶之实现listview的下拉加载
    android应用开发全程实录用户界面部分章节你真的会用最简单的TextView么?
    android应用开发全程实录你有多熟悉listview?
    android应用开发全程实录实现甩动拨打和挂断电话
    android应用开发全程实录关于google map的部分章节漂亮的气泡地图
    android UI进阶之用ViewPager实现欢迎引导页面
    android UI进阶之实现listview中checkbox的多选与记录
  • 原文地址:https://www.cnblogs.com/whywhy/p/4196248.html
Copyright © 2011-2022 走看看