HDU 1828 Picture(线段树 + 扫描线)
来源:互联网 发布:税控发票软件 编辑:程序博客网 时间:2024/06/01 09:59
题目链接:点击打开链接
题意:求n个矩形的周长的并。
思路:用扫描线法, 按照x坐标和y坐标分别扫描, 用线段树维护区间覆盖情况, yy了一下, 可以发现, 每次的可见轮廓都等于这次的区间覆盖长度和上一次的差值。
细节参见代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<stack>#include<bitset>#include<cstdlib>#include<cmath>#include<set>#include<list>#include<deque>#include<map>#include<queue>#define Max(a,b) ((a)>(b)?(a):(b))#define Min(a,b) ((a)<(b)?(a):(b))using namespace std;typedef long long ll;typedef long double ld;const ld eps = 1e-9, PI = 3.1415926535897932384626433832795;const int mod = 1000000000 + 7;const int INF = 0x3f3f3f3f;// & 0x7FFFFFFFconst int seed = 131;const ll INF64 = ll(1e18);const int maxn = 20000 + 10;int T,n,m,kase=0,addv[maxn<<2],sum[maxn<<2];struct edge { int xl, yl, xr, yr;}a[6000];struct node { int xl, xr, h, id; node(int xl=0, int xr=0, int h=0, int id=0):xl(xl),xr(xr),h(h),id(id) {} bool operator < (const node& rhs) const { if(h == rhs.h) return id > rhs.id; //注意, 这里一定要这样排序, 比如数据: 2 0 0 4 4 0 4 4 8 else return h < rhs.h; }}x[maxn],y[maxn];void PushUp(int l, int r, int o) { if(addv[o]) sum[o] = r+1 - l; //当前区间被线段覆盖 else if(l == r) sum[o] = 0; // 已经到了叶子结点且没有被覆盖 else sum[o] = sum[o<<1] + sum[o<<1|1]; // 没有完全被覆盖, 但是还没到叶子结点, 从其子区间中获得信息}void build(int l, int r, int o) { int m = (l + r) >> 1; addv[o] = sum[o] = 0; if(l == r) return ; build(l, m, o<<1); build(m+1, r, o<<1|1);}void update(int L, int R, int x, int l, int r, int o) { int m = (l + r) >> 1; if(L <= l && r <= R) { addv[o] += x; PushUp(l, r, o); return ; } if(L <= m) update(L, R, x, l, m, o<<1); if(m < R) update(L, R, x, m+1, r, o<<1|1); PushUp(l, r, o);}int xl, xr, yl, yr;int main() { while(~scanf("%d",&n)) { int cnt = 0, res = 0; int mx = -INF, my = -INF; for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&xl,&yl,&xr,&yr); xl += 10001; xr += 10001; yl += 10001; yr += 10001; if(xl > xr) swap(xl, xr); if(yl > yr) swap(yl, yr); x[cnt++] = node(xl, xr, yr, -1); x[cnt++] = node(xl, xr, yl, 1); y[res++] = node(yl, yr, xl, 1); y[res++] = node(yl, yr, xr, -1); mx = max(mx, xr); my = max(my, yr); } sort(x, x+cnt); sort(y, y+res); build(1, mx, 1); int cur = 0; ll ans = 0; for(int i=0;i<cnt;i++) { if(x[i].xl < x[i].xr) update(x[i].xl, x[i].xr-1, x[i].id, 1, mx, 1); ans += abs(sum[1] - cur); cur = sum[1]; } cur = 0; build(1, my, 1); for(int i=0;i<res;i++) { if(y[i].xl < y[i].xr) update(y[i].xl, y[i].xr-1, y[i].id, 1, my, 1); ans += abs(sum[1] - cur); cur = sum[1]; } printf("%I64d\n",ans); } return 0;}
0 0
- HDU 1828 Picture(线段树:扫描线)
- hdu 1828 Picture 线段树+扫描线
- 【HDU】1828-Picture(线段树扫描线)
- HDU 1828 Picture(线段树 + 扫描线)
- hdu 1828 Picture (线段树+扫描线)
- HDU 1828 Picture (线段树+扫描线+离散化)
- hdu 1828 Picture(线段树&扫描线&周长并)
- hdu 1828 Picture(线段树扫描线矩形周长并)
- HDU 1828 && POJ 1177 Picture(线段树+扫描线+离散化)
- HDU 1828——Picture(线段树+周长并+扫描线)
- poj 1177 || HDU 1828 Picture (线段树扫描线求 图形并的周长)
- HDU 1828 Picture(线段树扫描线·周长并)
- hdu 1828 Picture(线段树,扫描线之周长并)
- HDOJ 题目1828 Picture (线段树+扫描线)
- POJ 1177 Picture & hdu 1828 Picture(扫描线)
- hdu 1828(poj 1177)Picture(线段树+扫描线)(轮廓线)
- HDU 1828 Picture (线段树扫描线求周长并 区间合并)
- hdu 1828 Picture(扫描线)
- Android开发性能优化大总结
- Android so文件是32位时,如何在64位手机上运行。
- jquery选择器 之 获取父级元素、同级元素、子元素
- android启动出错
- VC串口超时参数结构体COMMTIMEOUTS [附 VC9下载地址]
- HDU 1828 Picture(线段树 + 扫描线)
- MATLAB数据降维工具箱drtoolbox介绍
- 博文的学习路线
- 互联网推送服务原理:长连接+心跳机制(MQTT协议)
- LCT 动态树 hdu 5002
- 2016峰会:项目管理与高级项目管理 - 图片花絮
- php提示undefined index的几种解决方法
- OSGI框架搭建常见问题即错误
- Spring进阶之路(8)-java代码与配置文件中配置