zoukankan      html  css  js  c++  java
  • HDU 5820 Lights(扫描线+zkw线段树)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5820

     

    【题目大意】

      在一个大小为50000*50000的矩形中,有n个路灯。

      询问是否每一对路灯之间存在一条道路,使得长度为|x1–x2|+|y1–y2|且每个拐弯点都是路灯。

    【题解】

      只要找到不共线的两个点,他们所构成的矩阵剩余的两个点都是不存在的,那么这个图就是违法的。那么如何找呢,我们将所有点按照x为第一关键字,y为第二关键字排序,逐行扫描,对于每个点,扫描与他同行的前后两个点的列坐标形成的区间,如果这个区间出现x坐标比这个点所在列上一个出现的点要大,那么就是非法的。所以剩下的就是线扫描和rmq问题了。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int U=50000,N=500005;
    int L,R,n,T[U<<2],v[N],x,y,M,ans;
    struct data{int x,y;}p[N];
    bool cmp(data a,data b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    bool check(){
        memset(T,0,sizeof(T)); 
        for(L=0,R=-1;L<n;L=R+1){
            while(R+1<n&&p[R+1].x==p[L].x)R++;
            for(int i=L;i<=R;i++){
                if(i>L&&p[i].y==p[i-1].y)continue;
                x=i==L?1:p[i-1].y+1;
                y=i==R?U:p[i+1].y-1;
                for(x=x+M-1,y=y+M+1,ans=0;x^y^1>0;x>>=1,y>>=1){
                    if(~x&1)ans=max(ans,T[x+1]);
                    if(y&1)ans=max(ans,T[y-1]);
                }if(ans>T[p[i].y+M])return 0;
            }for(int i=L;i<=R;i++){
                T[p[i].y+M]=p[i].x;
                for(int b=(p[i].y+M)/2;b;b/=2)T[b]=max(T[b<<1],T[(b<<1)^1]);
            }
        }return 1;
    }
    int main(){
        for(M=1;M<U+2;M<<=1);
        while(~scanf("%d",&n),n){
            for(int i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].y);
            sort(p,p+n,cmp);
            if(check())puts("YES");else puts("NO");
        }return 0;
    }
  • 相关阅读:
    cocos2d-x 游戏暂停界面,监听home键,返回键,Menu键 解决方案
    转载cocos2dx的各种动作用法
    cocso2d-x改变精灵图片
    cocos2d-x 菜单
    for循环
    nginx限制IP访问网站
    zabbix server in not running
    筛选nginx访问日志文件中的域名
    Zabbix历史数据清理
    http跳转http
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5820.html
Copyright © 2011-2022 走看看