E - 秋实大哥与家

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit Status

秋实大哥是一个顾家的男人,他认为人生就是旅途,不管我们漂到哪,最终还是会回到温暖的地方——家。

所以他买了很多家具。

秋实大哥的家可以看成一个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
2 2 2 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>的更多相关文章

  1. UESTC_秋实大哥搞算数 2015 UESTC Training for Data Structures<Problem N>

    N - 秋实大哥搞算数 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  2. UESTC_秋实大哥打游戏 2015 UESTC Training for Data Structures<Problem H>

    H - 秋实大哥打游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  3. UESTC_秋实大哥去打工 2015 UESTC Training for Data Structures<Problem G>

    G - 秋实大哥去打工 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  4. UESTC_秋实大哥与战争 2015 UESTC Training for Data Structures<Problem D>

    D - 秋实大哥与战争 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  5. UESTC_秋实大哥与快餐店 2015 UESTC Training for Data Structures<Problem C>

    C - 秋实大哥与快餐店 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

  6. UESTC_秋实大哥与花 2015 UESTC Training for Data Structures<Problem B>

    B - 秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. UESTC_秋实大哥与小朋友 2015 UESTC Training for Data Structures<Problem A>

    A - 秋实大哥与小朋友 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

  8. UESTC_秋实大哥掰手指 2015 UESTC Training for Dynamic Programming<Problem B>

    B - 秋实大哥掰手指 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 2048/1024KB (Java/Others) Submit ...

  9. UESTC_秋实大哥与线段树 2015 UESTC Training for Data Structures<Problem M>

    M - 秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

随机推荐

  1. 通过java类文件识别JDK编译版本

    类文件中第5,6,7,8四个字节是jDK版本号信息,其中5,6为小版本号:7,8为大版本号. 大版本号对应JDK版本如下: JDK版本号 7,8字节 JDK8 52(0x34) JDK7 51(0x3 ...

  2. 【转】UltraISO制作U盘启动盘安装Win7/9/10系统攻略

    U盘安装好处就是不用使用笨拙的光盘,光盘还容易出现问题,无法读取的问题.U盘体积小,携带方便,随时都可以制作系统启动盘. U盘建议选择8G及以上大小的. 下面一步一步讲解如果制作U盘安装盘: 1.首先 ...

  3. windows任务栏消失

    windows任务栏消失,快捷键打开任务管理器,新建任务explorer.exe

  4. SqlServer经典函数之数字去零

    需求: 针对带有小数点的数字信息,去除小数点后多余的零 可能存在的情况: 1.精度范围内,出现多余的零    eg:1234.3400     想要的结果为1234.34 2.精度变大出现的多余的零, ...

  5. Thinkphp 3.0版本上传文件加图片缩略图实例解析

    先看html加个表单,注意这里的action 路径要选 对. <div> <form action="__URL__/add_img" enctype=" ...

  6. Lua Table 操作

    Lua中table类似与C#种的字典,其实就是一个key-value键值对数据结构.来学习下table基本操作 Table的创建 myTable = {} --表名后面使用{}赋值,表示一个空的表 m ...

  7. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

  8. linux下git使用记录1 git 提交

    linux下git使用记录1   浏览:985 发布日期:2013/08/08 分类:技术分享 在使用github的时候,不可避免的接触到了git,用他来更新项目,做版本控制.这里特别把常用的命令记录 ...

  9. RMAN简单备份

    检查目标数据库是否处于归档模式: . 检查数据库模式: sqlplus /nolog conn /as sysdba archive log list (查看数据库是否处于归档模式中) 若为非归档,则 ...

  10. Android 4.4前后版本读取图库图片和拍照完美解决方案

    转载:http://blog.csdn.net/zbjdsbj/article/details/42387551 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了. 主要 ...