hdu 4052 Adding New Machine,set
2014-10-15 22:19
267 查看
hdu4052 Adding New Machine,set
比较老的题。给一个矩形和一些已经覆盖了的小矩形,问在剩余的空格上放一个长为m的条有多少种放法。
可以用线段树化为矩形面积并搞。这里练习一下平衡树的做法,set也比较短。
把矩形变为入和出两个事件,根据这些事件计算某行有多少空格,就能计算横着放有多少种放法。然后横竖各做一遍。
这里利用set可以找到插入线段的两端第一个非空位置。
注意几个地方:
1.long long
2.m为1的情况,横竖是一样的。
3.排序事件时,要先出后进。
比较老的题。给一个矩形和一些已经覆盖了的小矩形,问在剩余的空格上放一个长为m的条有多少种放法。
可以用线段树化为矩形面积并搞。这里练习一下平衡树的做法,set也比较短。
把矩形变为入和出两个事件,根据这些事件计算某行有多少空格,就能计算横着放有多少种放法。然后横竖各做一遍。
这里利用set可以找到插入线段的两端第一个非空位置。
注意几个地方:
1.long long
2.m为1的情况,横竖是一样的。
3.排序事件时,要先出后进。
#include<iostream> #include<cstdio> #include<cstring> #include<set> #include<algorithm> using namespace std; #define NN 50100 int m; set<int> st; struct rect{ int sx,sy,ex,ey; }r[NN]; struct node{ int sx,ex,t,tag; void init(int a,int b,int c,int d){ sx=a;ex=b;t=c;tag=d; } }ev[NN*2],nd; bool cmp(node x,node y){ if (x.t==y.t) return x.tag<y.tag; else return x.t<y.t; } int initeven1(int n,int w,int h){ int i; int ret=0; for(i=1;i<=n;++i){ nd.init(r[i].sy,r[i].ey,r[i].sx,1); ev[++ret]=nd; nd.init(r[i].sy,r[i].ey,r[i].ex+1,-1); if (nd.t<=w) ev[++ret]=nd; } nd.init(0,h+1,1,1); ev[0]=nd; nd.init(0,h+1,w+1,-1); ev[ret+1]=nd; sort(ev+1,ev+ret+1,cmp); return ret; } int initeven2(int n,int w,int h){ int i; int ret=0; for(i=1;i<=n;++i){ nd.init(r[i].sx,r[i].ex,r[i].sy,1); ev[++ret]=nd; nd.init(r[i].sx,r[i].ex,r[i].ey+1,-1); if (nd.t<=w) ev[++ret]=nd; } nd.init(0,h+1,1,1); ev[0]=nd; nd.init(0,h+1,w+1,-1); ev[ret+1]=nd; sort(ev+1,ev+ret+1,cmp); return ret; } int insert(node ev){ int ret=0; set<int>::iterator it; set<int>::iterator rit; int ll,rr,tmp; if (ev.tag<0){ it=st.find(ev.ex); rit=st.find(ev.sx); it++; rit--; ll=*rit; rr=*it; tmp=ev.sx-1-ll; if (tmp>=m) ret-=tmp+1-m; tmp=rr-1-ev.ex; if (tmp>=m) ret-=tmp+1-m; tmp=rr-1-ll; if (tmp>=m) ret+=tmp+1-m; st.erase(ev.sx); st.erase(ev.ex); } else{ st.insert(ev.sx); st.insert(ev.ex); it=st.find(ev.ex); rit=st.find(ev.sx); it++; rit--; ll=*rit; rr=*it; tmp=ev.sx-1-ll; if (tmp>=m) ret+=tmp+1-m; tmp=rr-1-ev.ex; if (tmp>=m) ret+=tmp+1-m; tmp=rr-1-ll; if (tmp>=m) ret-=tmp+1-m; } return ret; } long long work(int n,int tn,int w,int h){ int i; int t,tlen; long long sum=0,ret=0; st.clear(); insert(ev[0]); if (h>=m){ sum=h+1-m; } ret+=sum*(ev[1].t-1); for(i=1;i<=tn;){ t=ev[i].t; while(ev[i].t==t){ sum+=insert(ev[i]); ++i; } tlen=ev[i].t-t; ret+=sum*tlen; } return ret; } int n,w,h; int main(){ //freopen("bin.txt","r",stdin); int i,tn; long long ans1,ans2=0; while(scanf("%d%d%d%d",&w,&h,&n,&m)!=EOF){ for(i=1;i<=n;++i){ scanf("%d%d%d%d",&r[i].sx,&r[i].sy,&r[i].ex,&r[i].ey); } tn=initeven1(n,w,h); ans1=work(n,tn,w,h); if (m>1){ tn=initeven2(n,h,w); ans2=work(n,tn,h,w); } else ans2=0; printf("%I64d\n",ans1+ans2); } return 0; }
相关文章推荐
- HDU 4052 Adding New Machine(矩形面积并)
- Hdu 4052 Adding New Machine(给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)和(x2,y2)),问能下多少个1*M的矩形)
- hdu 4052 Adding New Machine
- HDU 4052 Adding New Machine(矩形面积并)
- hdu 4052 Adding New Machine(线段树+扫描线)
- HDU 4052 Adding New Machine (线段树)
- HDU 4052 Adding New Machine (线段树+离散化)
- [线段树]HDU 4052 Adding New Machine
- hdu-4052/ LA 5694-Adding New Machine(线段树矩形面积并)
- HDU 4052 Adding New Machine(矩形面积并)
- hdu 4052 Adding New Machine 扫描线求矩形面积并
- zoj 3540 Adding New Machine
- 在VMWare 中增加磁盘(Adding a new disk to a VMware Virtual Machine in Linux)
- zoj 3540 Adding New Machine
- UVA 1492 - Adding New Machine(线段树)
- Adding a new disk to a VMWare Virtual Machine in Linux
- UVA1492 - Adding New Machine(扫描线)
- UVA1492 - Adding New Machine(扫描线)
- hdu4052-Adding New Machine-题解
- 【HDU4052】【ZOJ3540】Adding New Machine 线段树+扫描线