UVA1492 LA5694 线段树扫描线(矩形面积合并)
来源:互联网 发布:苹果mac好用吗 编辑:程序博客网 时间:2024/04/30 09:51
我们考虑 每个新机器往右放的起始点(1*1的块)那么我们只要求出哪些位置不可以放就可以了,比如说 3*3 的矩阵 新机器长为2 旧机器在2 2 那么 1 1这个点就不可以放新机器(考虑机器往右放的起始点)再考虑右边界,右边界左边m-1个位置也不可以放再考虑往下放的起始点,同理了综上我们只要分别求出 哪些点不可以放 再用所有点减去就可以了其实这就转化成了求矩形面积合并的问题了注意特判m=1 横着放竖着放重复计算了线段树实现矩形面积合并时还是要注意一些细节,每个节点储存的是这个点到右边那个点的距离
#include <bits/stdc++.h>using namespace std;const int maxn=2e5+10;typedef long long ll;ll w,h,n,m;struct data{ ll x1,x2,y; int flag;} a[maxn<<2],b[maxn<<2];ll hasha[maxn],hashb[maxn];ll sum[maxn<<2];ll col[maxn<<2],flaga[maxn],flagb[maxn];inline bool cmp(data a,data b){ return a.y<b.y;}void pushup(ll s,ll l,ll r){ if(col[s]) sum[s]=hasha[r+1]-hasha[l]; else if(l==r) sum[s]=0; else { sum[s]=sum[s*2]+sum[s*2+1]; }}void update(ll L,ll R,ll l,ll r,ll flag,ll s){ if(L<=l&&R>=r) { col[s]+=flag; pushup(s,l,r); return ; } ll m=(l+r)/2; if(L<=m) { update(L,R,l,m,flag,s*2); } if(R>m) { update(L,R,m+1,r,flag,s*2+1); } pushup(s,l,r);}int main(){ while(~scanf("%lld%lld%lld%lld",&w,&h,&n,&m)) { for(int i = 1; i <= n; ++i) { ll xx1,yy1,xx2,yy2; scanf("%lld%lld%lld%lld",&xx1,&yy1,&xx2,&yy2); a[i*2].x1=a[i*2-1].x1=xx1-m+1>0?xx1-m+1:1; a[i*2].x2=a[i*2-1].x2=xx2+1; a[i*2-1].flag=1; a[i*2].flag=-1; hasha[i*2-1]=a[i*2-1].x1; hasha[2*i]=a[i*2].x2; a[i*2-1].y=yy1; a[i*2].y=yy2+1; b[i*2].x1=b[i*2-1].x1=yy1-m+1>0?yy1-m+1:1; b[i*2].x2=b[i*2-1].x2=yy2+1; b[i*2-1].y=xx1; b[i*2].y=xx2+1; hashb[i*2-1]=b[i*2-1].x1; hashb[2*i]=b[i*2].x2; b[i*2-1].flag=1; b[i*2].flag=-1; } memset(col,0,sizeof col); memset(sum,0,sizeof sum); a[2*n+2].x1=a[2*n+1].x1=w-m+2>0?w-m+2:1; a[2*n+1].flag=1; a[2*n+2].flag=-1; a[2*n+2].x2=a[2*n+1].x2=w+1; a[2*n+1].y=1; a[2*n+2].y=h+1; hasha[2*n+1]=a[n*2+1].x1; hasha[2*n+2]=a[n*2+2].x2; sort(a+1,a+2*n+3,cmp); sort(hasha+1,hasha+2*n+3); ll sz=unique(hasha+1,hasha+2*n+3)-hasha; long long ans=0; for(ll i = 1; i <= 2*n+2; ++i) { ll l=lower_bound(hasha+1,hasha+sz,a[i].x1)-hasha; ll r=lower_bound(hasha+1,hasha+sz,a[i].x2)-hasha-1; if(r>=l) update(l,r,1,sz-1,a[i].flag,1); ans+=sum[1]*(a[i+1].y-a[i].y); } for(ll i = 1; i <= 2*n+2; ++i) { hasha[i]=hashb[i]; a[i]=b[i]; } a[2*n+2].x1=a[2*n+1].x1=h-m+2>0?h-m+2:1; a[2*n+2].x2=a[2*n+1].x2=h+1; a[2*n+1].y=1; a[2*n+2].y=w+1; a[2*n+1].flag=1; a[2*n+2].flag=-1; hasha[2*n+1]=a[n*2+1].x1; hasha[2*n+2]=a[n*2+2].x2; memset(col,0,sizeof col); memset(sum,0,sizeof sum); sort(a+1,a+2*n+3,cmp); sort(hasha+1,hasha+2*n+3); sz=unique(hasha+1,hasha+2*n+3)-hasha; for(int i = 1; i <= 2*n+2; ++i) { ll l=lower_bound(hasha+1,hasha+sz,a[i].x1)-hasha; ll r=lower_bound(hasha+1,hasha+sz,a[i].x2)-hasha-1; if(r>=l) update(l,r,1,sz-1,a[i].flag,1); ans+=sum[1]*(a[i+1].y-a[i].y); } ans=(long long)w*h*2-ans; if(m==1) ans/=2; cout<<ans<<endl; } return 0;}
0 0
- UVA1492 LA5694 线段树扫描线(矩形面积合并)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- 矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)
- HDU1542 Atlantis(扫描线+矩形面积并+线段树)
- poj 1151 线段树+扫描线(Atlantis矩形面积)
- hdu 1542 矩形面积并(扫描线+线段树)
- FAFU-1398 面积 矩形面积并 线段树+扫描线
- POJ1151(线段树+扫描线求矩形面积并)
- 线段树求矩形面积并 扫描线+离散化
- hdu1542 线段树扫描线求矩形面积的并
- hdu1828 线段树扫描线求矩形面积的周长
- 线段树求矩形面积并 扫描线+离散化
- 扫描线+线段树求矩形面积的并
- 【poj1151】Atlantis(矩形面积并+线段树+扫描线)
- HDU3265 Posters(线段树,扫描线,矩形面积并)
- HDU3265(线段树+扫描线+挖空矩形面积并)
- HDU1542 POJ1151矩形面积合并(线段树+离散化)
- poj 1151 线段树+离散化+扫描线 矩形面积并 (矩阵操作类)
- Android遇到问题应该怎么解决
- 集合类总结笔记
- 以每行一个单词的形式打印其输入
- android View事件分发
- 常见对象_Arrays工具类的概述和使用
- UVA1492 LA5694 线段树扫描线(矩形面积合并)
- .gitignore中增加过滤规则不起作用的解决方法
- 浅谈 Observable和Observer 观察者模式
- 3-3-Java多线程-案例-银行存钱&同步函数
- golang https服务简单介绍
- 4-1-JDK1.5-Lock接口
- 5-1-Java多线程-练习-妖的出现和解决
- teamviewer一些按键冲突
- Java Arrays.asList()方法详解