UESTC_秋实大哥与家 2015 UESTC Training for Data Structures<Problem E>
E - 秋实大哥与家
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
秋实大哥是一个顾家的男人,他认为人生就是旅途,不管我们漂到哪,最终还是会回到温暖的地方——家。
所以他买了很多家具。
秋实大哥的家可以看成一个W×H的矩阵,每一件家具可以看成一个矩形,他们放置在秋实大哥的家里,相互之间没有重叠。
现在秋实大哥购置了一个新的大小为1×M的家具,秋实大哥想知道他有多少种方式来安放这个家具。
Input
第一行包含四个整数W,H,n,M,表示秋实大哥家的大小为W×H,现在已有n个家具,新购置的家具大小为1×M。
接下来n行,每行包含4个整数x1,y1,x2,y2,分别表示这个家具左下角的坐标和右上角的坐标。
1≤n,H,W,M≤100000,1≤x1≤x2≤W,1≤y1≤y2≤H。
Output
输出一行包含一个整数,表示有多少种方案可以来放置秋实大哥的新家具,要求不能跟原有的家具重叠,也不能超出家的范围。
Sample input and output
Sample Input | Sample Output |
---|---|
3 3 1 2 |
8 |
解题报告:
注意到所有的家具是1 x m的,不外乎横放与竖放,我们先考虑横放,对于每个矩形,其左端线坐标为x1,右端线坐标为x2.
那么下列这些点肯定无法放置的(以这些点为最左端放置)
(X1-m+1,x2) , y ∈ [y1,y2]
那么问题就好解决了,每读入一个矩形,将其线延长,之后算不合法的面积,用总面积减去不合法的面积即为方案数.
竖放的道理一样,这里不再阐述.注意到 m = 1的情况,横 / 竖是一样的
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
typedef long long ll;
using namespace std;
const int maxn = 6e5 + ;
const int maxtreesize = 6e5 + ;
int w,h,n,m,size=; typedef struct node
{
int l,r,cover,sum;
}; node tree[maxtreesize]; void push_up(int cur)
{
int lc = *cur;
int rc = *cur+;
if (tree[cur].cover)
tree[cur].sum = tree[cur].r - tree[cur].l;
else if(tree[cur].l == tree[cur].r ) // 叶子
tree[cur].sum = ;
else
{
if (tree[lc].cover && tree[rc].cover ) // Updata Father
tree[cur].sum = tree[lc].sum + tree[rc].sum;
else
tree[cur].sum = tree[lc].sum + tree[rc].sum;
} } void updata(int ql,int qr,int v,int cur)
{
int lc = *cur , rc = *cur + , l = tree[cur].l , r = tree[cur].r;
if (r == l) // 元
return;
if (l >= ql && r <= qr)
{
tree[cur].cover += v;
push_up(cur);
}
else
{
int mid = l + (r-l)/;
if (mid > ql)
updata(ql,qr,v,lc);
if (mid < qr)
updata(ql,qr,v,rc);
push_up(cur);
}
} void build_tree(int cur,int l,int r)
{
tree[cur].l = l,tree[cur].r = r;
if (r - l > )
{
int mid = l + (r-l)/;
build_tree(*cur,l,mid);
build_tree(*cur+,mid,r);
}
} typedef struct line
{
int x1,x2,y1,y2;
bool flag; // 0 是入边,1 是出边
inline int getx()
{
if (flag)
return x2;
else
return x1;
}
inline int gety()
{
if (flag)
return y2;
else
return y1;
}
}; line a[maxn]; // x 方向上被限制
line b[maxn]; // y 方向上被限制 bool cmp1(line a,line b)
{
return a.getx() < b.getx();
} bool cmp2(line a,line b)
{
return a.gety() < b.gety();
} void dump__()
{
for(int i = ; i < size ; ++ i)
{
if (a[i].flag == )
{
printf("入边 , x is %d , y1 is %d, y2 is %d\n",a[i].getx(),a[i].y1 , a[i].y2);
}
else
printf("出边 , x is %d , y1 is %d, y2 is %d\n",a[i].getx(),a[i].y1 , a[i].y2);
}
} void dump()
{
for(int i = ; i < size ; ++ i)
{
if (b[i].flag == )
{
printf("入边 , y is %d ,left is %d,right is %d\n",b[i].y1,b[i].x1,b[i].x2 );
}
else
{
printf("出边 , y is %d ,left is %d,right is %d\n",b[i].y2,b[i].x1,b[i].x2 );
}
}
} ll sall; //总面积 ll slove1()
{
ll res = ;
sort(a,a+size,cmp1);
int cur = ;
updata(a[].y1,a[].y2,,);
while(cur < size)
{
int dis = a[cur].getx() - a[cur-].getx();
res += (ll)dis*(ll)tree[].sum;
if (a[cur].flag & ) //出边
updata(a[cur].y1,a[cur].y2,-,);
else
updata(a[cur].y1,a[cur].y2,,);
cur++;
}
return sall - res;
} ll slove2()
{
ll res = ;
sort(b,b+size,cmp2);
int cur = ;
updata(b[].x1,b[].x2,,);
while(cur < size)
{
int dis = b[cur].gety() - b[cur-].gety();
res += (ll)dis*(ll)tree[].sum;
if (b[cur].flag & ) //出边
updata(b[cur].x1,b[cur].x2,-,);
else
updata(b[cur].x1,b[cur].x2,,);
cur++;
}
return sall - res;
} int main(int argc,char *argv[])
{
scanf("%d%d%d%d",&w,&h,&n,&m);
memset(tree,,sizeof(tree));
memset(a,,sizeof(a));
memset(b,,sizeof(b));
build_tree(,,max(w,h)+); // Build Tree
sall = (ll)w*(ll)h;
for(int i = ; i < n ; ++ i)
{
int x1,y1,x2,y2,oriy1,orix1;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1 -- , y1 -- ; //转换为线段式
orix1 = x1,oriy1 = y1;
x1 = x1-m+ >= ? x1-m+ : ;
y1 = y1-m+ >= ? y1-m+ : ;
a[size].x1 = x1,a[size].x2 = x2,a[size].y1 = oriy1 , a[size].y2 = y2 , a[size].flag = ;
b[size].x1 = orix1 , b[size].x2 = x2 , b[size].y1 = y1,b[size].y2 = y2 , b[size++].flag = ;
a[size].x1 = x1,a[size].x2 = x2,a[size].y1 = oriy1 , a[size].y2 = y2 , a[size].flag = ;
b[size].x1 = orix1 , b[size].x2 = x2 , b[size].y1 = y1,b[size].y2 = y2 , b[size++].flag = ;
}
ll ans = ;
a[size].x1 = w-m + >= ? w-m+ : , a[size].x2 = w , a[size].y1 = , a[size].y2 = h,a[size++].flag = ; //添加限制线
a[size].x1 = w-m + >= ? w-m+ : , a[size].x2 = w , a[size].y1 = , a[size].y2 = h,a[size++].flag = ;
ans += slove1();
size -= ;
b[size].x1 = ,b[size].x2 = w ,b[size].y1 = h-m+ >= ? h-m+ : ,b[size].y2 = h , b[size++].flag = ;
b[size].x1 = ,b[size].x2 = w ,b[size].y1 = h-m+ >= ? h-m+ : ,b[size].y2 = h , b[size++].flag = ;
ans += slove2();
if (m == )
printf("%lld\n",ans/);
else
printf("%lld\n",ans);
return ;
}
UESTC_秋实大哥与家 2015 UESTC Training for Data Structures<Problem E>的更多相关文章
- UESTC_秋实大哥搞算数 2015 UESTC Training for Data Structures<Problem N>
N - 秋实大哥搞算数 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Subm ...
- UESTC_秋实大哥打游戏 2015 UESTC Training for Data Structures<Problem H>
H - 秋实大哥打游戏 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Subm ...
- UESTC_秋实大哥去打工 2015 UESTC Training for Data Structures<Problem G>
G - 秋实大哥去打工 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Subm ...
- UESTC_秋实大哥与战争 2015 UESTC Training for Data Structures<Problem D>
D - 秋实大哥与战争 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Subm ...
- UESTC_秋实大哥与快餐店 2015 UESTC Training for Data Structures<Problem C>
C - 秋实大哥与快餐店 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Sub ...
- UESTC_秋实大哥与花 2015 UESTC Training for Data Structures<Problem B>
B - 秋实大哥与花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_秋实大哥与小朋友 2015 UESTC Training for Data Structures<Problem A>
A - 秋实大哥与小朋友 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Sub ...
- UESTC_秋实大哥掰手指 2015 UESTC Training for Dynamic Programming<Problem B>
B - 秋实大哥掰手指 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 2048/1024KB (Java/Others) Submit ...
- UESTC_秋实大哥与线段树 2015 UESTC Training for Data Structures<Problem M>
M - 秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Sub ...
随机推荐
- 【HDU1166】敌兵布阵(树状数组或线段树)
是一道树状数组的裸题,也可以说是线段树的对于单点维护的裸题.多做这种题目可以提高自己对基础知识的理解程度,很经典. #include <iostream> #include <cst ...
- SoftLayerDebug
- Pythoner | 你像从前一样的Python学习笔记
Pythoner | 你像从前一样的Python学习笔记 Pythoner
- wxpython 布局管理
一个典型的应用程序是由不同的部件.这些小部件被放进容器部件.一个程序员必须管理应用程序的布局.这不是一项容易的任务.在wxPython我们有两个选择. *absolute positioning*si ...
- Mac截屏快捷键总结
Mac截屏快捷键总结 1)Command-Shift-3: 将整个屏幕拍下并保存到桌面. 2)Command-Shift-Control-3: 将整个屏幕拍下并保存到剪贴板(Clipboard ...
- 文件atime未变问题的研究
1. atime, ctime 以及mtime 这三个名词属于文件/文件夹的属性,存在于inode数据结构之中. 通过系统调用stat可以获取stat结构,其中包括:atime(accesstime) ...
- HDU4907小技巧
原题http://acm.hdu.edu.cn/showproblem.php?pid=4907 Task schedule Time Limit: 2000/1000 MS (Java/Others ...
- 用函数式的 Swift 实现图片转字符画的功能
今天整理 Pocket 中待看的文章,看到这篇<Creating ASCII art in functional Swift>,讲解如何用 Swift 将图片转成 ASCII 字符.具体原 ...
- OMXCodec与OMX事件处理流程
学习了解Mutilmedia Framework有一段时间了,今天闲下来稍微整理整理.OMXCodec.cpp类属于libstagefright,在整个MM PF 相当OMX的适配层,供awesome ...
- 使用HttpClient发送GET请求
HttpRequestMessage http_req_msg = new HttpRequestMessage(); http_req_msg.Method = HttpMethod.Get; ht ...