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 ...
随机推荐
- HDU 1251 字典树(前缀树)
题目大意 :Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).(单词互不相同) ...
- 01_docker学习总结
01 docker学习总结 toolbox https://hub.docker.com/ https://docs.docker.com/engine/installation/mac/#from- ...
- JAVA获得系统配置文件的System Properties
来个java获得系统配置文件的 public class SystemProperties { public static void main(String[] args) { Properties ...
- ssh登录失败处理步骤
如果登录失败而又找不到显示的原因,优先使用ssh -vT name@ip -p port 进行调试,查看所使用的key文件.ip.端口是否正确.然后再检查下面步骤:1.检查在对应用户名下是否有iden ...
- iOS FMDB中的使用
n使用事务 [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [db executeUpdate:@"INSERT INTO ...
- 创建UILabel
UILabelCreate.h #import <UIKit/UIKit.h> @interface UILabelCreate : UILabel /** * 创建UILabel 初始化 ...
- Android应用程序线程消息循环模型分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是 ...
- 设计一个算法,求非空二叉树中指定的第k层(k>1)的叶子节点的个数
思想:採用基于层序遍历的方法. 用level扫描各层节点,若某一层的节点出队后.rear指向该层中最右节点.则将rear赋值给last(对于第一层.last=1).在出队时,若front=last,表 ...
- 1. Git 克隆代码
1. Git 克隆代码 git clone git://github.com/facebook/hiphop-php.git 2. Git更新分支 查看服务器上的所有分支 [huzg@slave3 h ...
- Linux下安装软件的错误
1. make configure GEN configure/bin/sh: 1: autoconf: not foundmake: *** [configure] Error 127 解决:sud ...