zoukankan      html  css  js  c++  java
  • HDU 5820 Lights (2016多校7L,主席树)

    题意  给定n个平面上的点,坐标范围为[1, 50000]。如果对于任意两个点,都可以通过直走(中途经过其他点)走到。

       那么输出YES,否则输出NO。

    首先排序,去重。

    我们要找的点对是只能斜对角走到的点。

    那么找到这个点正左边的离他最近的点和正上方最近的点。查询以这三个点为顶点的矩形的内部有没有其他点。

    如果有的话就找到了这样的点对,输出NO。

    用主席树实现,时间复杂度$O(nlogn)$。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    typedef long long LL;
    typedef pair <int, int> PII;
    
    const int N = 1e6 + 10;
    const int M = 5e4 + 10;
    
    PII a[N];
    map <PII, int> mp;
    int n, flag;
    int T;
    int num;
    int mx[M], my[M];
    int tot;
    int s[N << 3], ls[N << 3], rs[N << 3];
    int root[M];
    
    void update(int &x, int y, int l, int r, int pos){
    	x = ++tot;
    	s[x] = s[y] + 1;
    	if (l == r) return;
    	ls[x] = ls[y];
    	rs[x] = rs[y];
    	int mid = (l + r) >> 1;
    	if (pos <= mid) update(ls[x], ls[y], l, mid, pos);
    	else update(rs[x], rs[y], mid + 1, r, pos);
    }
    
    int query(int x, int y, int L, int R, int l, int r){
    	if (l <= L && R <= r) return s[y] - s[x];
    	int ret = 0;
    	int mid = (L + R) >> 1;
    	if (l <= mid) ret += query(ls[x], ls[y], L, mid, l, r);
    	if (r >  mid) ret += query(rs[x], rs[y], mid + 1, R, l, r);
    	return ret;
    }
    
    void work1(){
    	tot = 0;
    	memset(mx, 0, sizeof mx);
    	memset(my, 0, sizeof my);
    	memset(root, 0, sizeof root);
    	int last = root[0];
    	rep(i, 1, n){
    		int x1 = a[i].fi, y1 = a[i].se;
    		int x2 = a[my[y1]].fi, y2 = a[mx[x1]].se;
    		update(root[x1], last, 1, 50000, y1);
    		int cnt = query(root[x2], root[x1], 1, 50000, y2 + 1, y1);
    		if (cnt != 1){
    			flag = 0;
    			return;
    		}
    		mx[a[i].fi] = i;
    		my[a[i].se] = i;
    		last = root[x1]; 
    	}
    }
    
    int main(){
    
    	while (~scanf("%d", &n), n){
    		rep(i, 1, n){
    			scanf("%d%d", &a[i].fi, &a[i].se);
    		}
    
    		a[n + 1].fi = a[n + 1].se = 0;
    
    		sort(a + 1, a + n + 1);
    		n = unique(a + 1, a + n + 1) - a - 1;
    
    		flag = 1;
    		work1(); 
    		rep(i, 1, n) a[i].fi = 50001 - a[i].fi;
    		sort(a + 1, a + n + 1);
    		work1();
    		puts(flag ? "YES" : "NO" );
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    CSS复合选择器
    模块之shutil模块模块详解
    模块之sys模块详解
    模块之os模块详解
    map遍历
    java完美处理表情符
    死磕设计模式—建造者模式
    Java String getChars()方法
    Java知识系统回顾整理01基础06数组05复制数组
    Java知识系统回顾整理01基础06数组04增强型for循环
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/9804841.html
Copyright © 2011-2022 走看看