题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4052

初始给你w*h的矩阵,给你n个矩形(互不相交),按这些矩形尺寸把初始的矩形扣掉,形成一个新的'矩形'。然后给你1*m大小的矩形,问这个矩形在新'矩形'中有多少种放法。

一开始没想法==,然后看了看题解,说是线段树做的。

要是m为1的话,那答案就是剩下的面积了。

不为1的话,可以把n个矩形的面积扩展一下(我是向右扩展),比如x1 y1 x2 y2 的矩形扣掉,就相当于x1  y1  x2+m-1  y2的地方扣掉了,这种是x轴的情况。那么y轴的情况就是x1 y1 x2  y2+m-1。最左边也要扣掉,比如x轴就是0 0 m - 1 h。所以最后就是算剩下的面积了。(我的方法比较笨,就是x轴一个线段树扫一下,y轴一个线段树扫一下)

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
const int MAXN = 1e5 + ;
typedef long long LL;
LL fab(LL a) {
return (a > ? a : -a);
}
struct data {
int ll , rr , flag , l , r , h;
bool operator <(const data &cmp) const {
return h < cmp.h;
}
}line1[MAXN] , line2[MAXN];
struct segtree {
LL val;
int l , r , add;
}T1[MAXN * ] , T2[MAXN * ];
LL x[MAXN] , y[MAXN];
map <int , int> mp1 , mp2;
int f1 , f2; inline void add1(LL num) {
if(!mp1[num]) {
x[++f1] = num;
mp1[num] = ;
}
} inline void add2(LL num) {
if(!mp2[num]) {
y[++f2] = num;
mp2[num] = ;
}
} void pushupx(int p) {
if(T1[p].add) {
T1[p].val = x[T1[p].r] - x[T1[p].l];
}
else if(T1[p].r - T1[p].l == ) {
T1[p].val = ;
}
else {
T1[p].val = T1[p << ].val + T1[(p << )|].val;
}
} void pushupy(int p) {
if(T2[p].add) {
T2[p].val = y[T2[p].r] - y[T2[p].l];
}
else if(T2[p].r - T2[p].l == ) {
T2[p].val = ;
}
else {
T2[p].val = T2[p << ].val + T2[(p << )|].val;
}
} void buildx(int p , int l , int r) {
int mid = (l + r) >> ;
T1[p].l = l , T1[p].r = r , T1[p].val = T1[p].add = ;
if(r - l == ) {
return ;
}
buildx(p << , l , mid);
buildx((p << )| , mid , r);
} void buildy(int p , int l , int r) {
int mid = (l + r) >> ;
T2[p].l = l , T2[p].r = r , T2[p].val = T2[p].add = ;
if(r - l == ) {
return ;
}
buildy(p << , l , mid);
buildy((p << )| , mid , r);
} void updatex(int p , int l , int r , int add) {
int mid = (T1[p].l + T1[p].r) >> ;
if(T1[p].l == l && T1[p].r == r) {
T1[p].add += add;
pushupx(p);
return ;
}
if(r <= mid) {
updatex(p << , l , r , add);
}
else if(l >= mid) {
updatex((p << )| , l , r , add);
}
else {
updatex(p << , l , mid , add);
updatex((p << )| , mid , r , add);
}
pushupx(p);
} void updatey(int p , int l , int r , int add) {
int mid = (T2[p].l + T2[p].r) >> ;
if(T2[p].l == l && T2[p].r == r) {
T2[p].add += add;
pushupy(p);
return ;
}
if(r <= mid) {
updatey(p << , l , r , add);
}
else if(l >= mid) {
updatey((p << )| , l , r , add);
}
else {
updatey(p << , l , mid , add);
updatey((p << )| , mid , r , add);
}
pushupy(p);
} int main()
{
LL w , h , n , m , x1 , x2 , y1 , y2;
while(~scanf("%lld %lld %lld %lld" , &w , &h , &n , &m)) {
mp1.clear();
mp2.clear();
f1 = f2 = ;
if(m == ) {
LL sum = ;
while(n--) {
scanf("%lld %lld %lld %lld" , &x1 , &y1 , &x2 , &y2);
sum += (fab(x1 - x2) + ) * (fab(y1 - y2) + );
}
printf("%lld\n" , h * w - sum);
continue;
}
for(int i = ; i < n ; i++) {
scanf("%lld %lld %lld %lld" , &x1 , &y1 , &x2 , &y2);
x1-- , y1--;
int ls = i << , rs = (i << )|;
line1[ls].l = x1 , line1[ls].r = min(w , x2 + m - ) , line1[ls].h = y1 , line1[ls].flag = ;
line1[rs].l = x1 , line1[rs].r = line1[ls].r , line1[rs].h = y2 , line1[rs].flag = -;
line2[ls].l = y1 , line2[ls].r = min(h , y2 + m - ) , line2[ls].h = x1 , line2[ls].flag = ;
line2[rs].l = y1 , line2[rs].r = line2[ls].r , line2[rs].h = x2 , line2[rs].flag = -;
add1(line1[ls].l);
add1(line1[ls].r);
add1(line1[rs].l);
add1(line1[rs].r);
add2(line2[ls].l);
add2(line2[ls].r);
add2(line2[rs].l);
add2(line2[rs].r);
}
int ls = n << , rs = (n << )| , f = ((n << )|) + ;
line1[ls].l = , line1[ls].r = m - , line1[ls].h = , line1[ls].flag = ;
line1[rs].l = , line1[rs].r = m - , line1[rs].h = h , line1[rs].flag = -;
line2[ls].l = , line2[ls].r = m - , line2[ls].h = , line2[ls].flag = ;
line2[rs].l = , line2[rs].r = m - , line2[rs].h = w , line2[rs].flag = -;
add1(line1[ls].l);
add1(line1[ls].r);
add1(line1[rs].l);
add1(line1[rs].r);
add2(line2[ls].l);
add2(line2[ls].r);
add2(line2[rs].l);
add2(line2[rs].r);
sort(line1 , line1 + f);
sort(line2 , line2 + f);
sort(x + , x + f1 + );
sort(y + , y + f2 + );
for(int i = ; i < f ; i++) {
line1[i].ll = lower_bound(x + , x + f1 + , line1[i].l) - x;
line1[i].rr = lower_bound(x + , x + f1 + , line1[i].r) - x;
line2[i].ll = lower_bound(y + , y + f2 + , line2[i].l) - y;
line2[i].rr = lower_bound(y + , y + f2 + , line2[i].r) - y;
}
LL res1 = , res2 = ;
buildx( , , f1);
buildy( , , f2);
updatex( , line1[].ll , line1[].rr , line1[].flag);
updatey( , line2[].ll , line2[].rr , line2[].flag);
for(int i = ; i < f ; i++) {
res1 += (line1[i].h - line1[i - ].h) * T1[].val;
res2 += (line2[i].h - line2[i - ].h) * T2[].val;
updatex( , line1[i].ll , line1[i].rr , line1[i].flag);
updatey( , line2[i].ll , line2[i].rr , line2[i].flag);
}
printf("%lld\n" , h * w * - res1 - res2);
}
}

HDU 4052 Adding New Machine (线段树+离散化)的更多相关文章

  1. HDU 3743 Frosh Week (线段树+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 Frosh Week Time Limit : 2000/1000ms (Java/Other) ...

  2. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

  3. hdu 3333 Turing Tree(线段树+离散化)

    刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望. 刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的 ...

  4. HDU 4052 Adding New Machine(矩形面积并)

    Adding New Machine Problem Description Incredible Crazily Progressing Company (ICPC) suffered a lot ...

  5. HDU5124:lines(线段树+离散化)或(离散化思想)

    http://acm.hdu.edu.cn/showproblem.php?pid=5124 Problem Description John has several lines. The lines ...

  6. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

  7. poj 2528 Mayor's posters(线段树+离散化)

    /* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...

  8. [poj2528] Mayor's posters (线段树+离散化)

    线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...

  9. [UESTC1059]秋实大哥与小朋友(线段树, 离散化)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...

随机推荐

  1. MVVM设计模式《网摘》

    MVVM模式能够帮你把你程序的业务与展现逻辑从用户界面干净地分离开.保持程序逻辑与界面分离能够帮助解决很多开发以及设计问题,能够使你的程序能更容易的测试,维护与升级.它也能很大程度的增加代码重用性,并 ...

  2. bzoj1132

    每次都选最左边的点,然后以这个点为原点 统计和这个点构成的三角形面积和 不难想到极角排序然后由叉积很容易求出 shl ; eps=1e-8; var i,j,k,m,n:longint; x,y:.. ...

  3. socket编程---一个简单例子

    服务器端代码(单线程): import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamRe ...

  4. UVa 11997 (优先队列 多路归并) K Smallest Sums

    考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数. 将这n2个数拆成n个有序表: A1+B1≤A1+B2≤... A2+B1≤A2+B2≤. ...

  5. Drupal 7.31版本爆严重SQL注入漏洞

    今早有国外安全研究人员在Twitter上曝出了Drupal 7.31版本的最新SQL注入漏洞,并给出了利用测试的EXP代码. 在本地搭建Drupal7.31的环境,经过测试,发现该利用代码可成功执行并 ...

  6. Asp.Net时间戳与时间互转

    /// <summary> /// 时间戳转成时间类型 /// </summary> /// <param name="timeStamp">& ...

  7. Asp.Net IEnumerable,ICollection,IList,List区别

    做C#的同学们,都知道,一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: / ...

  8. Mysql 临时变量的 定义 和 赋值 Set 和 Into 赋值; Swith Mysql版本 Case When的用法

    一:临时变量的定义和赋值 DECLARE spot SMALLINT; -- 分隔符的位置 DECLARE tempId VARCHAR(64); -- 循环 需要用到的临时的Cid DECLARE ...

  9. solr4.2 solrconfig.xml配置文件简单介绍

    对于solr4.x的每个core有两个很重要的配置文件:solrconfig.xml和schema.xml,下面我们来了解solrconfig.xml配置文件. 具体很详细的内容请细读solrcofi ...

  10. 【转】http-equiv的含义

    http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...