POJ1177+线段树+扫描线
思路:
以y的值进行离散化
根据x的值 对每一条y轴边进行处理,如果是"左边"则插入,是"右边"则删除。
- /*
- 扫描线+线段树+离散化
- 求多个矩形的周长
- */
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<algorithm>
- #include<iostream>
- #include<queue>
- #include<stack>
- #include<math.h>
- #include<map>
- using namespace std;
- const int maxn = ;
- const int maxm = ;
- struct SegTree{
- int l,r;
- int len;//区间代表的长度
- int segnum;//区间被分成的段数
- int cover;//区间被覆盖的次数
- int sum;//区间被覆盖的总长度
- bool lcover,rcover;
- }ST[ maxm<< ];
- struct Line{
- int st,ed,x;//竖边的两个y值
- bool InOut;//是否为左边
- bool operator < (Line L) const{
- return x<L.x;
- }
- };
- Line yLine[ maxm ];
- int yIndex[ maxm ];
- int n;
- void build( int L,int R,int n ){
- ST[ n ].l = L;
- ST[ n ].r = R;
- ST[ n ].len = yIndex[ R ]-yIndex[ L ];
- ST[ n ].sum = ST[ n ].cover = ST[ n ].segnum = ;
- ST[ n ].lcover = ST[ n ].rcover = false;
- if( R-L> ){
- int mid = (L+R)/;
- build( L,mid,*n );
- build( mid,R,*n+ );
- }
- return ;
- }
- void Update_Len( int n ){
- if( ST[n].cover> ){
- ST[n].sum = ST[n].len;
- }
- else if( ST[n].r-ST[n].l> ){
- ST[n].sum = ST[*n].sum+ST[*n+].sum;
- }
- else
- ST[n].sum = ;
- }
- void Update_Segnum( int n ){
- if( ST[n].cover> ){
- ST[n].lcover = ST[n].rcover = true;
- ST[n].segnum = ;
- }
- else if( ST[n].r-ST[n].l> ){
- ST[n].lcover = ST[*n].lcover;
- ST[n].rcover = ST[*n+].rcover;
- ST[n].segnum = ST[*n].segnum+ST[*n+].segnum-ST[*n].rcover*ST[*n+].lcover;
- }
- else{
- ST[n].segnum = ;
- ST[n].lcover = ST[n].rcover = false;
- }
- }
- void PushUp ( int n ){
- Update_Len( n );//求节点包含的线段总长度
- Update_Segnum( n );
- }
- void Insert( int left,int right,int n ){
- if( ST[ n ].l==left&&ST[ n ].r==right ){
- ST[ n ].cover++;
- }
- else {
- int mid = (ST[ n ].l+ST[ n ].r)/;
- if( right<=mid )
- Insert( left,right,*n );
- else if( left>=mid )
- Insert( left,right,*n+ );
- else{
- Insert( left,mid,*n );
- Insert( mid,right,*n+ );
- }
- }
- PushUp( n );
- }
- void Delete( int left,int right,int n ){//删除矩形的右边
- if( ST[ n ].l==left&&ST[ n ].r==right ){
- ST[ n ].cover--;
- }
- else {
- int mid = (ST[ n ].l+ST[ n ].r)/;
- if( right<=mid )
- Delete( left,right,*n );
- else if( left>=mid )
- Delete( left,right,*n+ );
- else{
- Delete( left,mid,*n );
- Delete( mid,right,*n+ );
- }
- }
- PushUp( n );
- }
- int GetIndex( int value ,int cnt ){
- return lower_bound(yIndex,yIndex+cnt,value )-yIndex;
- }
- int main(){
- while( scanf("%d",&n)== ){
- int cnt = ;
- int x1,y1,x2,y2;
- for( int i=;i<n;i++ ){
- scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
- yLine[ *i ].x = x1;
- yLine[ *i+ ].x = x2;
- yLine[ *i ].st = yLine[ *i+ ].st = y1;
- yLine[ *i ].ed = yLine[ *i+ ].ed = y2;
- yLine[ *i ].InOut = true;
- yLine[ *i+ ].InOut = false;
- yIndex[ *i ] = y1;
- yIndex[ *i+ ] = y2;
- }
- sort( yIndex,yIndex+*n );
- sort( yLine,yLine+*n );
- for( int i=;i<*n;i++ ){
- if( yIndex[i]!=yIndex[i-] )
- yIndex[cnt++] = yIndex[i-];
- }
- yIndex[cnt++] = yIndex[*n-];
- build( ,cnt-, );
- int Ans = ;
- int PreSum = ;;//上一次记录的长度
- for( int i=;i<*n-;i++ ){
- if( yLine[i].InOut ){
- Insert( GetIndex(yLine[i].st,cnt),GetIndex(yLine[i].ed,cnt), );
- }
- else{
- Delete( GetIndex(yLine[i].st,cnt),GetIndex(yLine[i].ed,cnt), );
- }
- Ans += ST[].segnum**(yLine[i+].x-yLine[i].x);
- Ans += abs(ST[].sum-PreSum);
- PreSum = ST[].sum;
- }
- Delete( GetIndex(yLine[*n-].st,cnt),GetIndex(yLine[*n-].ed,cnt), );
- //特殊处理最后一条出边,因为没有下一条竖边了
- Ans += abs(ST[].sum-PreSum);
- printf("%d\n",Ans);
- }
- return ;
- }
POJ1177+线段树+扫描线的更多相关文章
- 【学习笔记】线段树—扫描线补充 (IC_QQQ)
[学习笔记]线段树-扫描线补充 (IC_QQQ) (感谢 \(IC\)_\(QQQ\) 大佬授以本内容的著作权.此人超然于世外,仅有 \(Luogu\) 账号 尚可膜拜) [学习笔记]线段树详解(全) ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞
看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
随机推荐
- C#根据WSDL文件生成WebService服务端代码
转自:http://www.cnblogs.com/liyi93/archive/2012/01/30/2332320.html 虽然现在已经进入了.NET FrameWork 4.0的时代,WebS ...
- SharePoint2013 SharePoint-Hosted 模式 分页方法
/**分页js插件 var ListPager = new listPaging(); 先调用start方法加载上下文 然后调用dataLoad方法查询第一页数据 需要设置几个属性值 ListPage ...
- Mysql数据库的索引原理
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...
- 认识JSON
JSON 全称 JavaScript Object Notation,意思是JavaScript对象表示法.是一种基于文本的.独立于语言的轻量级数据交换格式.易于阅读和编写,易于机器解析和生成. 一. ...
- SQLSERVER2012用户登录error40
昨天晚上公司停电了,电脑非正常关闭,今早回来之后,用sa登录sqlserver,一直报error40这个错,以前没碰到过,所以很紧张,问东问西,在网上也搜了好多,也跟着配置了好多,都不行,快被逼疯的时 ...
- 利用sys.dm_db_index_physical_stats查看索引碎片等数据(转)
我们都知道,提高sql server的数据查询速度,最有效的方法,就是为表创建索引,而索引在对数据进行新增,删除,修改的时候,会产生索引碎片,索引碎片多了,就需要重新组织或重新生成索引,以达到索引的最 ...
- 鼠标点击input时,placeholder中的提示信息消失
html代码: <input type="text" placeholder="多个关键词空格隔开"> 鼠标点击input时,placeholder ...
- TextView实现跑马灯效果
网上有很多跑马灯的介绍,有很多跑马灯的代码.或许我的不是最好的,但是应该很容易明白的. 我们先来介绍一个跑马灯的代码 <LinearLayout xmlns:android="http ...
- linq递归
public class Comment { public int Id { get; set; } public int ParentId { get; set; } public string T ...
- linux中的sticky bit
今天看到有个目录的权限是rwxrwxrwt 很惊讶这个t是什么,怎么不是x或者-呢?搜了下发现: 这个t代表是所谓的sticky bit. sticky bit: 该位可以理解为防删除位. 一个文件是 ...