Adding new machine
Problem descriptionincredible crazily progressing Company (ICPC) suffered a lot with the low speed of procedure. after investigation, they found that the bottleneck was at absolutely crowded manufactory (ACM ). in oder to accelerate the procedure, they bought a new machine for ACM. but a new problem comes, how to place the new machine into ACM?
ACM is a rectangular factor and can be divided into W * H cells. there are n Retangular old machines in ACM and the new machine can not occupy any cell where there is old machines. the new machine needs m consecutive cells. consecutive cells means some adjacent cells in a line. you are asked to calculate the number of ways to choose the place for the new machine.
Inputthere are multiple test cases (no more than 50 ). the first line of each test case contains 4 integers W, H, n, m (1 ≤ W, h ≤ 107, 0 ≤ n ≤ 50000, 1 ≤ m ≤ 1000 ), indicating the width and length of the room, the number of old machines and the size of the new machine. then n lines follow, each of which contains 4 integers xi1, yi1, xi2 and yi2 (1 ≤ xi1 ≤ xi2 ≤ W, 1 ≤ yi1 ≤ yi2 ≤ h ), indicating the coordinates of the I-th old machine. it is guarantees that no cell is occupied by two old machines.
Outputoutput the number of ways to choose the cells to place the new machine in one line.
Sample Input
3 3 1 22 2 2 23 3 1 32 2 2 22 3 2 21 1 1 12 3 2 3
Sample output
843
Authorguan, Yao
Source2011 Asia Dalian Regional Contest
Recommendlcy | we have carefully selected several similar problems for you: 4056 4059 4053 4057
Question:
The W * H lattice is now placed on N rectangles. Now you want to put an object with a length of M. How many methods do you have?
Solution:
Enumeration is useless.
(1) If an obstacle occurs, that is, if something occupies xi1, yi1, xi2, yi2, then max (xi1 + 1-m, 0 ), x2 y1y2 cannot be placed in this rectangular area.
(2) There is also a wall in front, that is, Max (0, W + 1-m), W, 0, H. This rectangular area cannot be placed.
If it is placed vertically, It is similar.
Pitfall: If M = 1, that is, horizontal and vertical is the same, you only need to consider one kind of situation. I got pitfall and played it 20 times.
Solution code:
#include <iostream>#include <vector>#include <cmath>#include <map>#include <cstdio>#include <algorithm>using namespace std;typedef long long ll;const int maxn=51000;struct node{ int l,r,pos,c; node(int l0=0,int r0=0,int pos0=0,int c0=0){ l=l0,r=r0,pos=pos0;c=c0; } friend bool operator < (node a,node b){ return a.pos<b.pos; }};struct rec{ int x1,y1,x2,y2;}d[maxn];vector <node> v;int w,h,m,n;vector <int> c;map <int,int> mp;struct Tree{ int l,r,cover,len;}tree[8*maxn];void build(int l,int r,int k){ tree[k].l=l; tree[k].r=r; tree[k].len=0; tree[k].cover=0; if(l+1>=r) return; int mid=(l+r)>>1; build(l,mid,k<<1); build(mid,r,k<<1|1);}void pushup(int k){ if(tree[k].cover>0) tree[k].len=c[tree[k].r]-c[tree[k].l]; else if(tree[k].l+1==tree[k].r) tree[k].len=0; else tree[k].len=tree[k<<1].len+tree[k<<1|1].len;}void insert(int l,int r,int k,int c0){ if(l<=tree[k].l && tree[k].r<=r){ tree[k].cover+=c0; } else{ int mid=(tree[k].l+tree[k].r)>>1; if(r<=mid) insert(l,r,k<<1,c0); else if(l>=mid) insert(l,r,k<<1|1,c0); else{ insert(l,mid,k<<1,c0); insert(mid,r,k<<1|1,c0); } } pushup(k);}ll getans(){ if(v.size()<=0) return (ll)w*(ll)h; c.clear(); mp.clear(); sort(v.begin(),v.end()); for(int i=0;i<v.size();i++){ mp[v[i].l]=i; mp[v[i].r]=i; } for(map <int,int>::iterator it=mp.begin();it!=mp.end();it++){ it->second=c.size(); c.push_back(it->first); } ll ret=0; build(0,c.size()-1,1); insert(mp[v[0].l],mp[v[0].r],1,v[0].c); for(int i=1;i<v.size();i++){ ret+=(ll)(v[i].pos-v[i-1].pos)*(ll)tree[1].len; insert(mp[v[i].l],mp[v[i].r],1,v[i].c); } return (ll)w*(ll)h-ret;}void solve(){ v.clear(); for(int i=0;i<n;i++){ v.push_back(node(max(d[i].x1+1-m,0),d[i].x2,d[i].y1,1)); v.push_back(node(max(d[i].x1+1-m,0),d[i].x2,d[i].y2,-1)); } if(m>1){ v.push_back(node(max(0,w+1-m),w,0,1)); v.push_back(node(max(0,w+1-m),w,h,-1)); } ll ans=getans(); if(m==1){ printf("%I64d\n",ans); return; } v.clear(); for(int i=0;i<n;i++){ v.push_back(node(max(d[i].y1+1-m,0),d[i].y2,d[i].x1,1)); v.push_back(node(max(d[i].y1+1-m,0),d[i].y2,d[i].x2,-1)); } if(m>1){ v.push_back(node(max(0,h+1-m),h,0,1)); v.push_back(node(max(0,h+1-m),h,w,-1)); } ans+=getans(); printf("%I64d\n",ans);}int main(){ while(scanf("%d%d%d%d",&w,&h,&n,&m)!=EOF){ for(int i=0;i<n;i++){ scanf("%d%d%d%d",&d[i].x1,&d[i].y1,&d[i].x2,&d[i].y2); d[i].x1--;d[i].y1--; } solve(); } return 0;}
HDU 4052 adding new machine (rectangular area and)