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. 杭电2059(dp)

    龟兔赛跑 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. c# list exists(contains) delegate 委托判断 元素是否在LIST中存在

    static void Main(string[] args)        {            List<GoodsInfo> list = new List<GoodsIn ...

  3. Hdu3487-Play with Chain(伸展树分裂合并)

    Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...

  4. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅲ

    2.4.3 堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的两个元素,以此类推. ...

  5. UVA 11374 Airport Express(枚举+最短路)

    枚举每条商业线<a, b>,设d[i]为起始点到每点的最短路,g[i]为终点到每点的最短路,ans便是min{d[a] + t[a, b] + g[b]}.注意下判断是否需要经过商业线.输 ...

  6. Hive 5、Hive 的数据类型 和 DDL Data Definition Language)

    官方帮助文档:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL Hive的数据类型 -- 扩展数据类型data_t ...

  7. py练习

    功能类似pop def myPop():    l=[]    a=raw_input('a:')    for i in a:        l.append(i)    l.pop()    pr ...

  8. 浅谈jquery关于select框的取值和赋值

    浅谈jquery关于select框的取值和赋值   jQuery("#select_id").change(function(){}); // 1.为Select添加事件,当选择其 ...

  9. CSS基础笔记

    之前没有开通好博客,笔记都记录在有道云,今天全部转过来!!! 1.当同一个html元素不止一个样式定义时,内联样式(在html元素内部)拥有最高的优先权:其他如内部样式表(位于<head> ...

  10. access数据库的连接字符串以及数据库操作类

    <!--access数据库连接方式--> <add name="QYTangConnectionString" connectionString="Pr ...