题目链接:

D. Vika and Segments

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-dimensional coordinate system on this sheet and drew n black horizontal and vertical segments parallel to the coordinate axes. All segments have width equal to 1 square, that means every segment occupy some set of neighbouring squares situated in one row or one column.

Your task is to calculate the number of painted cells. If a cell was painted more than once, it should be calculated exactly once.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of segments drawn by Vika.

Each of the next n lines contains four integers x1, y1, x2 and y2 ( - 109 ≤ x1, y1, x2, y2 ≤ 109) — the coordinates of the endpoints of the segments drawn by Vika. It is guaranteed that all the segments are parallel to coordinate axes. Segments may touch, overlap and even completely coincide.

Output

Print the number of cells painted by Vika. If a cell was painted more than once, it should be calculated exactly once in the answer.

Examples
input
30 1 2 11 4 1 20 3 2 3

output
8

input
4-2 -1 2 -12 1 -2 1-1 -2 -1 21 2 1 -2

output
16

Note

In the first sample Vika will paint squares (0, 1), (1, 1), (2, 1), (1, 2), (1, 3), (1, 4), (0, 3) and (2, 3).

题意:

给了这么多线段,问它们一共包含了多少个点;

思路:

把线段变成宽为1的矩形,然后用扫描线算法求面积;

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+4;
int n,x1,x2,y3,y2,rec[2*N],num;
struct no
{int l,r,h,flag;
};
no line[8*N];
struct nod
{int l,r,cover;ll sum;
};
nod tree[8*N];
int cmp(no x,no y)
{return x.h<y.h;
}
void build(int node,int L,int R)
{tree[node].l=L,tree[node].r=R;tree[node].cover=tree[node].sum=0;if(L>=R)return ;int mid=(L+R)>>1;build(2*node,L,mid);build(2*node+1,mid+1,R);
}
void Pushup(int node)
{if(tree[node].cover){tree[node].sum=rec[tree[node].r+1]-rec[tree[node].l];}else{if(tree[node].l==tree[node].r)tree[node].sum=0;else tree[node].sum=tree[2*node].sum+tree[2*node+1].sum;}
}
void update(int node,int L,int R,int x)
{if(L<=tree[node].l&&R>=tree[node].r){tree[node].cover+=x;Pushup(node);return ;}int mid=(tree[node].l+tree[node].r)>>1;if(L>mid) update(2*node+1,L,R,x);else if(R<=mid)update(2*node,L,R,x);else{update(2*node,L,mid,x);update(2*node+1,mid+1,R,x);}Pushup(node);
}
int bi(int x)
{int L=1,R=num-1,mid;while(L<=R){mid=(L+R)>>1;if(rec[mid]==x)return mid;else if(rec[mid]>x)R=mid-1;else L=mid+1;}return -1;
}
int main()
{scanf("%d",&n);int cnt=1;for(int i=1;i<=n;i++){scanf("%d%d%d%d",&x1,&y3,&x2,&y2);if(x1>x2)swap(x1,x2);if(y3>y2)swap(y3,y2);rec[cnt] = line[cnt].l = x1;line[cnt].r = x2+1;line[cnt].h = y3;line[cnt++].flag = 1;line[cnt].l = x1;rec[cnt] = line[cnt].r = x2+1;line[cnt].h = y2+1;line[cnt++].flag = -1;}sort(line+1,line+cnt,cmp);sort(rec+1,rec+cnt);num = 2;for(int i = 2;i < cnt;i++){if(rec[i]!=rec[i-1])rec[num++]=rec[i];}build(1,1,num-1);ll ans=0;for(int i = 1;i < cnt-1;i++){int fx = bi(line[i].l);int fy = bi(line[i].r)-1;if(fx <= fy){update(1,fx,fy,line[i].flag);}ans+=tree[1].sum*(ll)(line[i+1].h-line[i].h);}cout<<ans<<"\n";return 0;
}

  

转载于:https://www.cnblogs.com/zhangchengc919/p/5363831.html

codeforces 610D D. Vika and Segments(离散化+线段树+扫描线算法)相关推荐

  1. hdu-1542 Atlantis(离散化+线段树+扫描线算法)

    题目链接: Atlantis Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/32768 K (Java/Others) ...

  2. 610D - Vika and Segments(线段树+扫描线+离散化)

    扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html 看图,图中的数字是横坐标离散后对应的下标,计算时左端点不 ...

  3. [牛客网#35D 树的距离]离散化+线段树合并

    [牛客网#35D 树的距离]离散化+线段树合并 分类:Data Structure SegMent Tree Merge 1. 题目链接 [牛客网#35D 树的距离] 2. 题意描述 wyf非常喜欢树 ...

  4. CodeForces - 1401 F Reverse and Swap(线段树, 区间翻转, 区间交换,清晰易懂)

    CodeForces - 1401 F Reverse and Swap(线段树, 区间翻转, 区间交换)   首先一共有四个操作,第一个和第四个都是线段树的基本操作,直接用线段树实现.      第 ...

  5. poj/OpenJ_Bailian - 2528 离散化+线段树

    传送门:http://bailian.openjudge.cn/practice/2528?lang=en_US //http://poj.org/problem?id=2528 题意: 给你n长海报 ...

  6. 【BZOJ1645】[Usaco2007 Open]City Horizon 城市地平线 离散化+线段树

    [BZOJ1645][Usaco2007 Open]City Horizon 城市地平线 Description Farmer John has taken his cows on a trip to ...

  7. 850. 矩形面积 II:扫描线+离散化+线段树

    Difficulty: hard 标签: 扫描线, 离散化, 线段树 题目链接 力扣 题目解析 面试代码 /** x轴方向使用扫描线,y轴方向使用线段树维护扫描线的长度和每个区间覆盖的次数.由于y轴方 ...

  8. Codeforces Round #345 (Div. 1) D. Zip-line 上升子序列 离线 离散化 线段树

    D. Zip-line 题目连接: http://www.codeforces.com/contest/650/problem/D Description Vasya has decided to b ...

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

    题意: 在1~10000000这个区间中读取n个海报的区间信息,后面的海报会覆 盖前面的海报,问最后能看到几张海报.(本题是一道bug题下面会提) 题目: The citizens of Byteto ...

最新文章

  1. 【Javascript】之eval()
  2. virtual DOM和真实DOM的区别_让虚拟DOM和DOMdiff不再成为你的绊脚石
  3. 排序---对二维数组的排序
  4. 第三次学JAVA再学不好就吃翔(part11)--基础语法之switch语句
  5. 想使用Docker容器?先看看这些注意事项
  6. 快速排序详解+各种实现方式
  7. java is a like a_JAVA基础——is-a 、have-a、和 like-a的区别
  8. Linux 该文件命令查看内容
  9. bp神经网络预测模型python,bp神经网络预测模型
  10. Ubuntu中下载安装NVIDIA显卡驱动
  11. 动图在线压缩怎么操作?教你快速压缩动图
  12. 复数矩阵相乘的扩展矩阵计算方法
  13. 又一个程序猿的奋斗史——第二章 实习
  14. Cocos2d-x 3.2键盘操控列表页的初步实现
  15. 用html画一个企鹅图案的代码,6张思维导图,帮你搞定html、css(css画QQ企鹅)
  16. 红米10xpro手机图纸
  17. 前端必备知识储存——HTML篇一(面试常考)
  18. HyperLynx(三十二)高速串行总线仿真(四)
  19. paper:DeepAR: Probabilistic forecasting with autoregressive recurrent networks DeepAR模型
  20. 有关绩效考核系统的一些想法

热门文章

  1. php日期选择插件,优雅的日期选择插件daterangepicker
  2. linux 执行程序 注销,Linux登录登出的过程 | Soo Smart!
  3. 计算机二级ms office excel,计算机二级Msoffice考试excel答案.docx
  4. mysql查询日期胜负_MySQL面试题:查询每个日期的胜负次数
  5. android约束布局中 链,Android-ConstraintLayout(约束布局)-Chains链(链条布局,Nice)
  6. java获取当月1号 的时间chuo_java 获取昨天,上个星期一,本月开始时间戳,怎么写呢?...
  7. 织梦生成html加速,加快DEDECMS静态html网页生成速度的方法
  8. OpenCV中的特征匹配+单应性以查找对象
  9. halcon与QT联合:(5.2)瓶盖检测以及QT界面搭建
  10. Modbus协议在串行链路上的实现