洛谷题目链接:[USACO5.5]矩形周长Picture

题目背景

墙上贴着许多形状相同的海报、照片。它们的边都是水平和垂直的。每个矩形图片可能部分或全部的覆盖了其他图片。所有矩形合并后的边长称为周长。

题目描述

编写一个程序计算周长。

如图1所示7个矩形。

如图2所示,所有矩形的边界。所有矩形顶点的坐标都是整数。

输入输出格式

输入格式:

输入文件的第一行是一个整数N(0<=N<5000),表示有多少个矩形。接下来N行给出了每一个矩形左下角坐标和右上角坐标(所有坐标的数值范围都在-10000到10000之间)。

输出格式:

输出文件只有一个正整数,表示所有矩形的周长。

输入输出样例

输入样例#1:

7
-15 0 5 10
-5 8 20 25
15 -4 24 14
0 -6 16 4
2 15 10 22
30 10 36 20
34 0 40 16

输出样例#1:

228

题意: 给出一堆矩形,要你计算周长.

题解: 类似一堆矩形要你求某些信息的,基本上都可以用扫描线来做.

首先还是将矩形拆成线按照坐标排序,然后我们需要在线段树中记录几个变量:\(cov\)表示这个区间被覆盖的长度,\(sum\)表示这个区间的和(我们会在每次加入线段的时候给区间加上一个权值,会直接修改在\(sum\)变量里,但是\(sum\)标记不会下放).

接下来考虑如何写\(push\_up\)函数.首先判断一个节点被覆盖的长度先要看这个节点的\(sum\)是否有值,因为任何加入/删除线段的操作都会对\(sum\)进行修改,那么如果\(sum\)有值,显然\(cov=r-l+1\)(我这里使用的是闭区间).

如果\(sum\)的值为\(0\)呢?这时候我们需要判断这个节点是否为叶子节点,如果是叶子节点则\(cov=0\),否则\(cov=cov_{lson}+cov_{rson}\),判断是否为叶子的原因是防止越界.

然后查询的时候直接返回\(1\)节点的\(cov\)值就是整个区间内的覆盖数了.

那么答案如何统计呢?我这里是将\(x,y\)轴分两次求的,实际上可以一次做完,但是我自己\(yy\)的时候没想到这么多...

其实我们只需要每次插入一条线段,然后加入这次插入后\(cov\)的变化量的绝对值就可以了.

不懂可以看下代码.

#include<bits/stdc++.h>
#define ll(x) (x << 1)
#define rr(x) (x << 1 | 1)
using namespace std;
const int N = 10000+5;int n, cnt[2], ans = 0;struct line{ int x, l, r, v; }a[2][N*2];bool cmp(line a, line b){ return a.x != b.x ? a.x < b.x : a.v > b.v; }struct SegmentTree{ int l, r, sum, cov; }t[2][N*8];void up(int x, int k){if(t[k][x].sum) t[k][x].cov = t[k][x].r-t[k][x].l+1;else if(t[k][x].l == t[k][x].r) t[k][x].cov = 0;else t[k][x].cov = t[k][ll(x)].cov+t[k][rr(x)].cov;
}void build(int x, int l, int r, int k){t[k][x].l = l, t[k][x].r = r, t[k][x].sum = t[k][x].cov = 0;if(l == r) return; int mid = (l+r>>1);build(ll(x), l, mid, k), build(rr(x), mid+1, r, k);
}void update(int x, int l, int r, int val, int k){if(l <= t[k][x].l && t[k][x].r <= r){t[k][x].sum += val, up(x, k); return;}int mid = (t[k][x].l+t[k][x].r>>1);if(l <= mid) update(ll(x), l, r, val, k);if(mid < r) update(rr(x), l, r, val, k); up(x, k);
}void solve(int k){int last = 0, pos = 1; build(1, 1, N*2, k);sort(a[k]+1, a[k]+cnt[k]+1, cmp);for(pos = 1; pos <= cnt[k]; pos++){update(1, a[k][pos].l, a[k][pos].r-1, a[k][pos].v, k); //int add = abs(t[k][1].cov-last);ans += abs(t[k][1].cov-last), last = t[k][1].cov;}
}int main(){ios::sync_with_stdio(false);int a1, b1, a2, b2; cin >> n;for(int i = 1; i <= n; i++){cin >> a1 >> b1 >> a2 >> b2;a1 += N, b1 += N, a2 += N, b2 += N;a[0][++cnt[0]] = (line){ a1, b1, b2, 1 };a[0][++cnt[0]] = (line){ a2, b1, b2, -1 };a[1][++cnt[1]] = (line){ b1, a1, a2, 1 };a[1][++cnt[1]] = (line){ b2, a1, a2, -1 };}solve(0), solve(1);cout << ans << endl;return 0;
}

转载于:https://www.cnblogs.com/BCOI/p/10423238.html

[洛谷P1856] [USACO5.5]矩形周长Picture相关推荐

  1. 洛谷P1856 [USACO5.5]矩形周长Picture

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  2. 洛谷[P1719 最大加权矩形] {前缀和与差分} 奋斗的珂珂~

    洛谷[P1719 最大加权矩形] {前缀和与差分} 题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电 ...

  3. 洛谷1345 [Usaco5.4]奶牛的电信

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...

  4. 洛谷P1709 [USACO5.5]隐藏口令Hidden Password

    P1709 [USACO5.5]隐藏口令Hidden Password 题目描述 有时候程序员有很奇怪的方法来隐藏他们的口令.Binny会选择一个字符串S(由N个小写字母组成,5<=N<= ...

  5. 洛谷 P2746 [USACO5.3]校园网Network of Schools (Tarjan,SCC缩点,DAG性质)

    P2746 [USACO5.3]校园网Network of Schools https://www.luogu.org/problem/P2746 题目描述 一些学校连入一个电脑网络.那些学校已订立了 ...

  6. 拆分-洛谷P2745 [USACO5.3]窗体面积Window Area

    https://www.luogu.org/problem/show?pid=2745 本来因为会WA的,结果AC了,啊哈哈哈哈哈哈哈哈哈 因为题目要求我们要把一个个平面有先后关系,那么我们就搞一个队 ...

  7. 洛谷 P1719 最大加权矩形

    P1719 最大加权矩形 题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她 ...

  8. 洛谷 P1719 最大加权矩形 (前缀和,动态规划)

    题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她们都是电脑组的高手,校长没 ...

  9. 洛谷 P1719 最大加权矩形 动态规划

    题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她们都是电脑组的高手,校长没 ...

最新文章

  1. Linux下备份系统
  2. Objective-C中的Category
  3. mini2440 裸机编程 -led
  4. windows 8 “Fetch”远程获取
  5. Java并发包--线程池框架
  6. 使用内存回流的方法来实现将image的内容转换为 byte[]
  7. 给linux内核传递数组,数组与指针 - Linux C编程实战之路_Linux编程_Linux公社-Linux系统门户网站...
  8. IP转发的最长前缀匹配
  9. c#中excel文件怎么转换为dbf文件
  10. 垃圾邮件过滤python_手把手教你用 python 和 scikit-learn 实现垃圾邮件过滤-阿里云开发者社区...
  11. 基于网络信息安全技术管理的计算机应用研究
  12. 确定有限自动机DFA和非确定有限自动机NFA
  13. c语言计算二元一次不定方程,二元一次不定方程的解
  14. rpm搭建LAMP+Discuz论坛
  15. Java 实现PDB数据库中蛋白质部分序列与Uniport数据库中相应的全长序列的最优匹配
  16. allegro输出gerber过孔盖孔
  17. Word批量转TXT宏
  18. pyhon 函数 输入输出
  19. 正弦波SFR分辨率测试卡
  20. Rust嵌入式编程---动态内存分配器(Vec,String等)

热门文章

  1. 命名实体识别python_命名实体识别的两种方法
  2. 《自然语言处理实战入门》第三章 :中文分词原理及相关组件简介 ---- 工业级词法分析组件百度LAC2.0
  3. JST日本压着端子PH系列线对板连接器的PCB封装库
  4. android 查看文件夹大小 删除文件,Android Base64编码保存本地。查询文件夹大小以及删除...
  5. 设计模式笔记--备忘录模式
  6. win10服务器 稳定性,如何检测Win10系统稳定性?
  7. 教你判断一个APP页面是原生的还是H5页面
  8. Pointpillars三维点云实时检测
  9. 用python画花瓣-用python画花瓣
  10. 地下水情监测仪应用库区安全行业