题意:

给出n个矩形,求被覆盖区域为奇数次的总面积。

思路:

扫描线有很多种写法,可以打lazy更新到底,也可以不打lazy,只是单纯对目标边进行更新,然后再区间合并上去。

本题问的是被覆盖区域为奇数次的总面积。因此线段树每个节点记录被覆盖的次数,被覆盖奇数次的长度,被覆盖偶数次的长度。每次加入一条边,只对被覆盖的那个最大的区间,覆盖次数+1,对于该区间下面的区间不再进行更新,之后也不会更新。

因此假如第一次加入的线段是(1,4),第二次加入的线段是(1,2),因此第一次(1,4)区间覆盖次数变为1,第二次(1,2)区间覆盖次数变为1。然后区间合并的时候,len1表示覆盖奇数次的长度,len2表示覆盖偶数次的长度,(1,2)区间len1 = 1,len2 = 0. (1,4)区间覆盖次数为奇数,因此len1 = (1,2)与(3,4)区间被覆盖偶数次的长度,因为偶+奇 = 奇,而len2 = (1,2)与(3,4)区间被覆盖奇数次的长度。因此可以发现,虽然在加入直线的时候,没有将更新次数一次性更新到底,但是在区间合并的时候,会将之前覆盖的长度一并算入。

由于每次插入直线的时候,最后都会合并到整根扫描线上,因此询问整根扫描线的奇偶长度得到的答案是正确的。但是如果询问某一个区间被覆盖奇数次的长度则会得到错误答案,因为这个区间被覆盖的次数还取决于这个区间之上的区间。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
const int N = 2*1e5+1000;
typedef long long ll;struct Line{ll x,y1,y2;int flag;
}line[N];
int n, num;
ll y[N], ans;
struct Tree{int l,r,s;ll ml,mr,len1,len2; //记录覆盖偶数次的长度 和 覆盖奇数次的长度
}t[N*4];bool cmp(Line a,Line b)
{return a.x < b.x;
}void build(int p,int l,int r)
{t[p].l = l, t[p].r = r, t[p].ml = y[l], t[p].mr = y[r], t[p].s = 0, t[p].len1 = y[r]-y[l], t[p].len2 = 0;
//  cout << t[p].ml << " " << t[p].mr << endl;if(l == (r-1)) return;int mid = (l+r)>>1;build(p*2,l,mid);build(p*2+1,mid,r);
}void calc(int p)
{//len1:覆盖偶数次,len2:覆盖奇数次if(t[p].s % 2){    //覆盖奇数次if(t[p].r == (t[p].l+1)) t[p].len2 = t[p].mr-t[p].ml, t[p].len1 = 0;else{t[p].len1 = t[p*2].len2+t[p*2+1].len2;t[p].len2 = t[p*2].len1+t[p*2+1].len1;// t[p].len2 = t[p].mr-t[p].ml-t[p*2].len2-t[p*2+1].len2;}}else if(t[p].s % 2 == 0){ //覆盖偶数次if(t[p].r == (t[p].l+1)) t[p].len1 = t[p].mr-t[p].ml, t[p].len2 = 0;else{// t[p].len1 = t[p].mr-t[p].ml-t[p*2].len2-t[p*2+1].len2;t[p].len1 = t[p*2].len1+t[p*2+1].len1;t[p].len2 = t[p*2].len2+t[p*2+1].len2;}}
}void change(int p, Line tp)
{if(tp.y1 <= t[p].ml && tp.y2 >= t[p].mr){t[p].s += tp.flag;calc(p);return;}if(t[p*2].mr >= tp.y2) change(p*2,tp);else if(t[p*2+1].ml <= tp.y1) change(p*2+1,tp);else{change(p*2,tp);change(p*2+1,tp);} calc(p);
}int main()
{ans = 0, num = 0;scanf("%d",&n);rep(i,1,n){ll x1,x2,y1,y2;scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);line[++num].x = x1, line[num].y1 = y1, line[num].y2 = y2, line[num].flag = 1;y[num] = y1;line[++num].x = x2, line[num].y1 = y1, line[num].y2 = y2, line[num].flag = -1;         y[num] = y2;}sort(line+1,line+1+num,cmp);sort(y+1,y+1+num);int sc = unique(y+1,y+num+1)-y-1; build(1,1,sc);change(1,line[1]);rep(i,2,num){// printf("%f\n",t[1].len2);ans += t[1].len2*(line[i].x-line[i-1].x);change(1,line[i]);}cout << ans << endl;return 0;
}
/*
6
0 0 7 7
1 4 3 6
4 1 6 3
2 1 5 5
2 1 4 4
3 2 5 4
*/

【2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) F】Rectangles【扫描线】相关推荐

  1. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    gdcpc前一天上午搞了场训练,水题挺多,还算增强信心.(这么简单的题目居然还是div1,这赛区-- 最终9题,平均每人3题,我写ACF.被hry压了一道E (难受啊. 下午去中大试机,win7系统就 ...

  2. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 【部分题解】

    A:因为删除是不计入操作次数的,所以转化一下就是求最长上升子序列,简单dp. 设dp[i]表示前i个字符能凑成上升子序列的最大长度,dp[i] = max(dp[j]+1, dp[i]) [j < ...

  3. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) - D Count The Bits

    题目链接 Given an integer k and a number of bits b (1 ≤ b ≤ 128), calculate the total number of 1 bits i ...

  4. Gym 101982 (2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) )

    传送门: Problem A 温暖的签到题 #include<bits/stdc++.h> using namespace std; const int maxn=1007; char s ...

  5. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)DCount The Bits(dp/数位dp)

    D Count The Bits 题意: 输入k,b(1≤k≤1000,1≤b≤128);k,b(1\leq k\leq 1000,1\leq b\leq128);k,b(1≤k≤1000,1≤b≤1 ...

  6. 2016 ACM / ICPC Asia dalian Regional Contest 题解(11 / 11)【每日亿题2021 / 2 / 17】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A .(2017 ACM ICPC dalian H)To begin or not to be ...

  7. 2017 ACM ICPC Asia Shenyang Regional Contest 题解(10 / 13)【每日亿题2 / 16】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.(2017 ICPC shenyang I)Little Boxes B.(2017 ICP ...

  8. 2013-2014 ACM-ICPC Pacific Northwest Regional Contest题解

    ProblemSet A by ? B by ? 先Floyd求出两两之间最短路. 二分答案,新建一个图,<=x点对连距离为1的边 再施展Floyd,判断,最远两点距离<=k C by ? ...

  9. The 2019 ICPC Asia Shanghai Regional Contest

    The 2019 ICPC Asia Shanghai Regional Contest 题号 题目 知识点 A Mr. Panda and Dominoes B Prefix Code C Maze ...

  10. 2018 ICPC Asia Jakarta Regional Contest

    2018 ICPC Asia Jakarta Regional Contest 题号 题目 知识点 难度 A Edit Distance B Rotating Gear C Smart Thief D ...

最新文章

  1. 智慧城市建设:科技创业的下一个浪潮
  2. 方立勋_30天掌握JavaWeb_div和css基础
  3. msdn中C#中常用词汇概念(转帖)
  4. Linux密码是一个回文,usermod命令和用户密码管理
  5. 首页显示登陆用户名php,首页登录后怎么在首页显示用户名以及隐藏登录框?
  6. 4乘4方格走的路线_苏州周边4个冷门自驾游路线景点推荐
  7. mysql 添加表索引_如何向MySQL表中添加索引?
  8. 右键新建文件夹_教你修改Windows万年不变的黄色文件夹,让文件也不枯燥
  9. WAP常见问题问答大全
  10. Windows下Mirth连接Sybase数据库
  11. 创业者应该问投资人的10个问题
  12. 计算机网络设备的运行温度,什么是机房温度、湿度标准?
  13. vvebo源码学习(一)
  14. 使用 PyTorch 搭建网络 - predict_py篇
  15. 敢问路在何方 路在脚下
  16. 原来华为的鸿蒙就是换皮安卓,OPPO公关抖出鸿蒙是安卓换皮的猛料,结果被骂到辞职...
  17. 最新PHP开源采集器/蓝天采集器系统源码
  18. 程序员工具网站(比较有意思)
  19. Html中的特殊字符全部替换问题
  20. 客户端与服务器(C/S架构与B/S架构)、AJax学习

热门文章

  1. css样式,层叠顺序属性z-index
  2. svn版本内容信息存放路径
  3. linux内核启动的优化
  4. 置为底层_C语言之C语言的底层操作
  5. 2021最新SSM博客,功能完善,初云博客增强版
  6. python 通过逗号分割字符串_「Python 秘籍」使用多个界定符分割字符串
  7. 中常用的数据结构_代码面试需要知道的8种数据结构(附面试题及答案链接)
  8. 手把手教你python实现量价形态选股知乎_Python实现量化选股
  9. 【持续更新】最小生成树题目集合
  10. android局域网调试无法安装,真机调试出现:INSTALL_FAILED_USER_RESTRICTED 安装错误解决方案...