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 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.
Sample Input
3
0 1 2 1
1 4 1 2
0 3 2 3
Sample Output
8
Hint
题意
在平面上会画n条宽度为1的线
然后问你最后画出来的线的总面积是多少
题解:
把画出来的线当成矩形
然后就是扫描线的裸题了
线段树跑一波就吼了
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
typedef long long LL;
const int N=360005;
struct Line
{
int x,y1,y2,flag;
Line(){}
Line(int a,int b,int c,int d)
{ x=a;y1=b;y2=c;flag=d; }
bool operator<(const Line&b)const
{ return x<b.x; }
};
struct node
{
int lft,rht;
int len[12],flag;
int mid(){return MID(lft,rht);}
void init(){memset(len,0,sizeof(len));}
};
int n,k;
vector<int> y;
vector<Line> line;
map<int,int> H;
struct Segtree
{
node tree[N*4];
void calu(int ind)
{
if(tree[ind].flag>=k)
{
int tmp=tree[ind].len[0];
tree[ind].init();
tree[ind].len[k]=tree[ind].len[0]=tmp;
}
else if(tree[ind].flag>0)
{
int sum=0,cov=tree[ind].flag;
for(int i=1;i<=k;i++) tree[ind].len[i]=0;
tree[ind].len[cov]=tree[ind].len[0];
if(tree[ind].lft+1==tree[ind].rht) return;
for(int i=1;i<=k;i++)
{
if(i+cov>=k) tree[ind].len[k]+=tree[LL(ind)].len[i]+tree[RR(ind)].len[i];
else tree[ind].len[i+cov]=tree[LL(ind)].len[i]+tree[RR(ind)].len[i];
}
for(int i=cov+1;i<=k;i++) sum+=tree[ind].len[i];
tree[ind].len[cov]-=sum;
}
else
{
for(int i=1;i<=k;i++) tree[ind].len[i]=0;
if(tree[ind].lft+1==tree[ind].rht) return;
for(int i=1;i<=k;i++)
tree[ind].len[i]=tree[LL(ind)].len[i]+tree[RR(ind)].len[i];
}
}
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft; tree[ind].rht=rht;
tree[ind].init(); tree[ind].flag=0;
tree[ind].len[0]=y[rht]-y[lft];
if(lft+1!=rht)
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid,rht,RR(ind));
}
}
void updata(int st,int ed,int ind,int valu)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) tree[ind].flag+=valu;
else
{
int mid=tree[ind].mid();
if(st<mid) updata(st,ed,LL(ind),valu);
if(ed>mid) updata(st,ed,RR(ind),valu);
}
calu(ind);
}
}seg;
int main()
{
scanf("%d",&n);
k=1;
for(int i=0;i<n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1>x2)swap(x1,x2);
if(y1>y2)swap(y1,y2);
x2++;y2++;
line.push_back(Line(x1,y1,y2,1));
line.push_back(Line(x2,y1,y2,-1));
y.push_back(y1); y.push_back(y2);
}
sort(line.begin(),line.end());
sort(y.begin(),y.end());
y.erase(unique(y.begin(),y.end()),y.end());
for(int i=0;i<(int)y.size();i++) H[y[i]]=i;
seg.build(0,(int)y.size()-1,1);
LL res=0;
for(int i=0;i<(int)line.size();i++)
{
if(i!=0) res+=(LL)(line[i].x-line[i-1].x)*seg.tree[1].len[k];
seg.updata(H[line[i].y1],H[line[i].y2],1,line[i].flag);
}
cout<<res<<endl;
return 0;
}
Codeforces Round #337 (Div. 2) D. 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 Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树
C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树
题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...
- Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
- Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash
E. Kefa and Watch Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/prob ...
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)
题目:http://codeforces.com/problemset/problem/356/A 题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所 ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树
E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...
随机推荐
- Python编程中的反模式
Python是时下最热门的编程语言之一了.简洁而富有表达力的语法,两三行代码往往就能解决十来行C代码才能解决的问题:丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务 ...
- manacher算法_求最长回文子串长度
很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...
- 剑指offer
今天完成了剑指offer上的66道编程题,感觉自己还是很多代码实现能力和算法积累都还不够!还需要继续联系,坚持自己独立写代码实现. 最后将今天的两道题目奉上,都有异曲同工之妙: 矩阵中的路径: #in ...
- linux安装lua相关编译报错
1.报之类的错误 /usr/lib/libreadline.so: undefined reference to `PC' /usr/lib/libreadline.so: undefined ref ...
- 数据结构 -- 图的最短路径 Java版
作者版权所有,转载请注明出处,多谢.http://www.cnblogs.com/Henvealf/p/5574455.html 上一篇介绍了有关图的表示和遍历实现.数据结构 -- 简单图的实现与遍历 ...
- 【多线程】Java线程面试题 Top 50(转载)
Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎 ...
- codeforces 601A The Two Routes(最短路 flody)
A. The Two Routes time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- AVAST 4.8
AVAST专业版注册序列号不能用了就换一个继续注册,接着用序列号:S9665355R9665P1106-YCX4AKKT (2012.5.3)S7592769R8591F1106-ZVDJPMLT ( ...
- all & any
def all(*args, **kwargs): """ Return True if bool(x) is True for all values x in the ...
- UVaLive 6809 Spokes Wheel (模拟)
题意:给定两个16进制数,问你把它转成二进制后,把第一个向左或者向右旋转最少的次数同,使得第一个变成第二个. 析:也是比较水的,按照要求做就好,注意0的情况,可能会忘记. #pragma commen ...