610D - Vika and Segments(线段树+扫描线+离散化)
扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
看图,图中的数字是横坐标离散后对应的下标,计算时左端点不变,右端点加1,所以总的更新的区间是l到r-1。
也可以理解为1代表的是(1到2这一段),2代表的是(2到3这一段),3代表的是(3到4这一段)。。。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define ls rt<<1,l,m
#define rs rt<<1|1,m+1,r
#define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+;
struct line
{
int x1,x2;
int h;
int cover;
bool operator < (const line &t)
{
return h<t.h;
}
};
vector<line>l;
vector<int>w;
struct Tree
{
int l,r;
int sum;
int cover;
}tree[N*]; void push_up(int rt)
{
if(tree[rt].cover)
{
tree[rt].sum=w[tree[rt].r+]-w[tree[rt].l];
}
else
{
if(tree[rt].l==tree[rt].r)tree[rt].sum=;
else tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
} void build(int rt,int l,int r)
{
tree[rt].sum=tree[rt].cover=;
tree[rt].l=l,tree[rt].r=r;
if(l==r)return ;
int m=(l+r)>>;
build(ls);
build(rs);
} void Update(int L,int R,int delta,int rt,int l,int r)
{
if(L<=l&&r<=R)
{
tree[rt].cover+=delta;
push_up(rt);
return ;
}
int m=(l+r)>>;
if(L<=m)Update(L,R,delta,ls);
if(R>m)Update(L,R,delta,rs);
push_up(rt);
} int binasrh(int val,int l,int r)
{
int m;
while(l<=r)
{
m=(l+r)>>;
if(w[m]==val)return m;
else if(w[m]<val)l=m+;
else r=m-;
}
return -;
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,x1,x2,y1,y2;
cin>>n;
for(int i=;i<n;i++)
{
cin>>x1>>y1>>x2>>y2;
if(x1>x2||y1>y2)
{
swap(x1,x2);
swap(y1,y2);
}
x2++;
y2++;
l.pb(line{x1,x2,y1,});
l.pb(line{x1,x2,y2,-});
w.pb(x1);
w.pb(x2);
}
sort(w.begin(),w.end());
sort(l.begin(),l.end());
w.erase(unique(w.begin(),w.end()),w.end()); ll ans=;
build(,,w.size()-);
for(int i=;i<l.size()-;i++)
{
int L=binasrh(l[i].x1,,w.size()-);
int R=binasrh(l[i].x2,,w.size()-);
if(L<R)Update(L,R-,l[i].cover,,,w.size()-);
ans+=(ll)tree[].sum*(l[i+].h-l[i].h);
} cout<<ans<<endl;
return ;
}
610D - Vika and Segments(线段树+扫描线+离散化)的更多相关文章
- Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)
题目链接:http://codeforces.com/contest/610/problem/D 就是给你宽度为1的n个线段,然你求总共有多少单位的长度. 相当于用线段树求面积并,只不过宽为1,注意y ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线
D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...
- Codeforces 610D Vika and Segments 线段树+离散化+扫描线
可以转变成上一题(hdu1542)的形式,把每条线段变成宽为1的矩形,求矩形面积并 要注意的就是转化为右下角的点需要x+1,y-1,画一条线就能看出来了 #include<bits/stdc++ ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/POJ-1177 A number of rectangular posters, photographs and other pict ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- js五星好评
一般我们在一些购物以及美食的网站都会看到五星好评之类的,一下是使用js制作的五星好评! <!DOCTYPE html> <html lang="en"> & ...
- QLabel 文本内容自动换行显示
需要把QLabel的WordWrap属性设置成TRUE,可以通过界面设置,也可以通过程序设置
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- js文本框字数限制
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 20155227 2016-2017-2 《Java程序设计》第九周学习总结
20155227 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC简介 JDBC全名Java DataBase Connectivity,是java联 ...
- 【kafka学习之二】Kafka集群搭建
安装环境 jdk1.7 zookeeper-3.4.5(参考 https://www.cnblogs.com/cac2020/p/9426531.html) VM虚拟机redhat6.5-x64 ...
- python , 顺序迭代合并后的list对象
有一系列排序序列,想将它们合并后得到一个排序序列并在上面迭代遍历 heapq.merge() 函数可以帮你解决这个问题.比如: >>> import heapq >>&g ...
- python函数里面,一个*是可变参数的元祖,两个*是可变参数的字典
python的函数中,有时会有类似*args,**keys这样的参数,代表的是可变参数,一个*表示元祖,两个*表示字典,就是说这个函数可以接受任何类型的参数,都不会报错,有些函数为了提高可用性,会加这 ...
- WiFi攻击的三种方式
WiFi的安全问题已经引起了不少的使用者重视,甚至已经出现草木皆兵的现象.那么黑客到底是如何做到绕过身份验证来获取WiFi使用权的呢?主要有以下三种方式,其中最后一种方式十分简单. WiFi的安全问题 ...
- (一)github之基础概念篇
1.github: 一项为开发者提供git仓库的托管服务, 开发者间共享代码的场所.github上公开的软件源代码全都由git进行管理. 2.git: 开发者将源代码存入名为git仓库的资料库中,而g ...