题目链接:http://poj.org/problem?id=1177

题意:给你n个矩形问你重叠后外边缘总共多长。

周长并与面积并很像只不过是处理的时候是   增加的周长=abs(上一次的线段的长度-更新后线段的长度)

然后分别处理一下竖着的边和横着的边就好了即建两次树就好。

就是一道典型的周长并问题,可以拿来练练周长并的写法。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
const int M = 1e5 + 10;
struct ss {
int l , r , h , flag;
}s1[M << 1] , s2[M << 1];
struct TnT {
int l , r , add , len;
}T[M << 4];
bool cmp(ss a , ss b) {
if(a.h == b.h)
return a.flag > b.flag;
return a.h < b.h;
}
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r , T[p].add = T[p].len = 0;
if(l == r)
return ;
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
}
void pushup(int p) {
if(T[p].add) {
T[p].len = T[p].r - T[p].l + 1;
}
else if(T[p].l == T[p].r) {
T[p].len = 0;
}
else {
T[p].len = T[p << 1].len + T[(p << 1) | 1].len;
}
}
void updata(int l , int r , int p , int ad) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
T[p].add += ad;
pushup(p);
return ;
}
if(mid >= r) {
updata(l , r , p << 1 , ad);
}
else if(mid < l) {
updata(l , r , (p << 1) | 1 , ad);
}
else {
updata(l , mid , p << 1 , ad);
updata(mid + 1 , r , (p << 1) | 1 , ad);
}
pushup(p);
}
int main() {
int n;
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++) {
int x1 , y1 , x2 , y2;
scanf("%d%d%d%d" , &x1 , &y1 , &x2 , &y2);
x1 += M , x2 += M , y1 += M , y2 += M;
s1[i].flag = 1;
s1[i].l = x1;
s1[i].r = x2;
s1[i].h = y1;
s1[i + n].flag = -1;
s1[i + n].l = x1;
s1[i + n].r = x2;
s1[i + n].h = y2;
s2[i].flag = 1;
s2[i].l = y1;
s2[i].r = y2;
s2[i].h = x1;
s2[i + n].flag = -1;
s2[i + n].l = y1;
s2[i + n].r = y2;
s2[i + n].h = x2;
}
sort(s1 + 1 , s1 + 1 + 2 * n , cmp);
sort(s2 + 1 , s2 + 1 + 2 * n , cmp);
int l , r;
build(1 , 2 * M , 1);
ll ans = 0;
for(int i = 1 ; i <= 2 * n ; i++) {
int last = T[1].len;
l = s1[i].l;
r = s1[i].r - 1;
updata(l , r , 1 , s1[i].flag);
ans += abs(last - T[1].len);
}
build(1 , 2 * M , 1);
for(int i = 1 ; i <= 2 * n ; i++) {
int last = T[1].len;
l = s2[i].l;
r = s2[i].r - 1;
updata(l , r , 1 , s2[i].flag);
ans += abs(last - T[1].len);
}
printf("%lld\n" , ans);
return 0;
}

最新文章

  1. List集合的remove一个对象的方法
  2. Maven基础配置—上传jar包到私服
  3. BizTalk开发系列(十九) BizTalk命名规范
  4. mybaits入门
  5. SqlServer查看各个表所占空间大小的sql
  6. WPF TabControl 模拟动画
  7. hdu-5686 Problem B(斐波那契数列)
  8. spm使用之五修改spm自带文档主题模板
  9. 将使用netTcp绑定的WCF服务寄宿到IIS7上全记录 (这文章也不错)
  10. java学习笔记day05
  11. Chrome浏览器扩展开发系列之十:桌面通知Notification
  12. HDU1197 Specialized Four-Digit Numbers
  13. 清北学堂4.28Day1(重大更新详见贪心例一)
  14. [Swift]LeetCode881. 救生艇 | Boats to Save People
  15. Integer简介
  16. eclipse 构建 jpa project 所需的用户库(vendor: EclipseLink)
  17. (转)JavaWeb学习之Servlet(四)----ServletConfig获取配置信息、ServletContext的应用
  18. 获取img的高
  19. Netty---相关
  20. 10 ORM 多表操作 查询

热门文章

  1. JS 自执行函数
  2. 关于Unity 中对UGUI制作任务系统的编程
  3. Jenkins 配置 SpringBoot 自动构建部署
  4. Git命令备忘录
  5. 洛谷P2125 题解
  6. 【Java例题】2.4求函数
  7. GDOI#348大陆争霸[SDOI2010]最短路有限制条件
  8. RE最全面的正则表达式----终结篇 特殊处理
  9. 【0801 | Day 6】Python基础(四)
  10. Shiro权限注解原理