题目链接:

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
3
0 1 2 1
1 4 1 2
0 3 2 3
output
8
input
4
-2 -1 2 -1
2 1 -2 1
-1 -2 -1 2
1 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;
}

  

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. 【20.51%】【codeforces 610D】Vika and Segments

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. Educational Codeforces Round 23 F. MEX Queries 离散化+线段树

    F. MEX Queries time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  5. 南阳理工 题目9:posters(离散化+线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

  6. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

  7. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  8. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

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

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

随机推荐

  1. C语言-字符串

    问题: 给出的区分大小写的字母字符的字符串,找到最大的字符串X,或者为X,或者其逆可以找到任何给定的字符串的子串 输入: 输入文件的第一行包含一个整数t(1 < = t < = 10),测 ...

  2. spring-struts-mybatis整合错误集锦

    尽管三大框架特别特别的好用,可是,当我第一次把这三个框架用maven整合到一起的时候.各种错误接踵而至,以下来做一下三大框架整合的总结: 首先是在导入三大框架的各种依赖包的时候,由于我用的是j2ee  ...

  3. iOS中 扫描二维码/生成二维码具体解释 韩俊强的博客

    近期大家总是问我有没有关于二维码的demo,为了满足大家的需求,特此研究了一番,希望能帮到大家! 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 指示根视图: se ...

  4. ThinkPHP中的模型命名

    当我们创建一个UserModel类的时候,其实已经遵循了系统的约定.ThinkPHP要求数据库的表名和模型类的命名遵循一定的规范,首先数据库的表名和字段全部采用小写形式,模型类的命名规则是除去表前缀的 ...

  5. Allegro skill

    https://blog.csdn.net/wyu0725/article/details/52367199 Allegro skill二次开发和更改菜单页面 简单的使用skill;能够使Aleggr ...

  6. STM32单片机和51单片机区别

    单片机 / AVR / PIC / STM32 / 8051803189C5189S51 6905 单片机简介 单片微型计算机简称单片机,简单来说就是集CPU(运算.控制).RAM(数据存储-内存). ...

  7. 常见的CPU訪问引起的内存保护问题为什么仅仅用event_122上报 - 举例2

    还有一个样例.通过以下的log看,CPU在訪问reserved的地址0x53611EFD.非法訪问时该地址会在L1D内存控制器的L1DMPFSR寄存器中记录. ** FATAL EXCEPTION N ...

  8. VS中单元测试用法

    using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTestProject1 { [Test ...

  9. 跨平台.NET Core--微软开源方向

     跨平台.NET Core--微软开源方向 微软宣布.net开源已经有一段时间了,新的跨平台的.net框架叫.NET Core. 当前支持Windows/Linux/OSX/Docker.官网:h ...

  10. mysql双机热备+heartbeat集群+自动故障转移

    环境说明:本环境由两台mysql 数据库和heartbeat 组成,一台的ip 为 192.168.10.197,一台为192.168.10.198,对外提供服务的vip 为192.168.10.20 ...