zoukankan      html  css  js  c++  java
  • 【BZOJ】2078: [POI2004]WYS

    题意:

    给n个互不相交的多边形(边均平行于坐标轴),问最大深度。深度的定义是,若多边形A被多边形B包含,则(dep[A]=max(dep[B])+1)。坐标系的深度为0。(n<=40000,顶点个数<=200000)

    题解:

    扫描线+动态维护区间。
    考虑从左往右枚举交x轴平行于y轴的扫描线,维护每一个多边形在这条扫描线上能包含的最大(y)区间。
    在任意时刻,这段区间都是连续的,因此我们只需维护两个端点。

    将点离散,扫描线扫描的是所有点的x轴坐标。将所有点按照x为第一关键字、y为第二关键字,升序排序。然后从小到大枚举每个点。

    令当前枚举到的点为(p)点,所在多边形为(A)
    然后我们在这些要么包含要么不交的区间的端点中找一个点(q),满足(y_q>y_p)(y_q)最小,(q)所在多边形为(B)
    由于我们是从左往右扫,而且多边形互不相交,因此问题转化为求当前端点被多少个区间包含的问题。

    考虑这两种情况:
    1、被(q)点所在区间包含,则(dep[A]=dep[B]+1)
    2、没有被包含,则(dep[A]=dep[B])

    那么我们如何判断包含呢?我们在维护的两个端点打上这样的标记:
    一个多边形的边((u, v)),方向为逆时针方向,假设方向为((u->v)),则我们标记边的终点(v)
    则可以发现如果这个(q)是有标记的,则(A)没有被(B)包含。否则被(B)包含。
    证明就是分类讨论几种情况即可。

    现在来考虑如何维护每个多边形包含的区间。
    由于一个多边形内每个点的(x)轴出现次数一定是偶数次。而由于排序后的性质,每条有向边的起点就加入到区间,终点则去掉。

    到此本题解决。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=200005;
    int n, d[40005], ans, tot;
    struct ip {
    	int x, y, id;
    	bool flag;
    	bool operator < (const ip &a) const {
    		return x==a.x?y<a.y:x<a.x;
    	}
    }p[N];
    map<int, ip *>mp;
    void work() {
    	sort(p+1, p+1+tot);
    	map<int, ip *>::iterator it;
    	for(int i=1; i<=tot; ++i) {
    		int y=p[i].y;
    		it=mp.find(y);
    		if(it!=mp.end()) {
    			mp.erase(it);
    		}
    		else {
    			mp[y]=&p[i];
    			int id=p[i].id;
    			if(!d[id]) {
    				it=mp.upper_bound(y);
    				if(it==mp.end()) {
    					d[id]=1;
    				}
    				else {
    					if(it->second->flag) d[id]=d[it->second->id];
    					else d[id]=d[it->second->id]+1;
    				}
    			}
    		}
    	}
    	for(int i=1; i<=n; ++i) {
    		ans=max(ans, d[i]);
    	}
    }
    int main() {
    	scanf("%d", &n);
    	for(int i=1; i<=n; ++i) {
    		int k, x[2], t;
    		scanf("%d%d", &k, &x[0]);
    		t=x[0];
    		for(int j=1; j<=k; ++j) {
    			if(j!=k) scanf("%d", &x[j&1]);
    			else x[0]=t;
    			p[++tot]=(ip){x[0], x[1], i, (bool)(j&1)};
    		}
    	}
    	work();
    	printf("%d
    ", ans);
    	return 0;
    }
  • 相关阅读:
    Make a web page as screensaver
    python写入sqlserver中文乱码问题
    单片机中的ROM,RAM和FLASH的作用
    单片机STM32F4系统内部中断和外部中断优先级问题
    单片机AHB和APB
    嵌入式编程中一些常用的转换函数
    'AVStream::codec': 被声明为已否
    Python安装Python_snappy安装失败
    .net core 数据库问题
    .net 5.0 中 CrystalQuartz 增加授权校验
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985706.html
Copyright © 2011-2022 走看看