Codeforces 35E Parade 扫描线 + list
主题链接:点击打开链接
意甲冠军:特定n矩阵(总是接近底部x轴)
然后找到由上面的矩阵所包围的路径,的点
给定n
以下n行给定 y [x1, x2] 表示矩阵的高度和2个x轴坐标
思路:
扫描线维护每段区间的线段 最大的y值
则我们訪问每一个x轴坐标,就相当于訪问x轴坐标向右最短的那个小区间上的最大y值。
则能够得到[x,y] 和 [x+1, y] 这样2个点
当我们发现存在高度差时(且x轴不同样)
那么则手动加入一个点(这个点一定是与y大的点的x同样,y小的点的y同样)
再把3个相邻点且有同样y值的中间点删除。
再在首尾各添加一个底边的点就可以。
由于涉及链表的添加和删除。所以用stl的list。
#include <cstdio>
#include <algorithm>
#include<map>
#include<vector>
#include<list>
using namespace std;
#define N 400010
#define L(x) (x<<1)
#define R(x) (x<<1|1)
struct node{
int l,r;
int y, mid;
}tree[N<<2];
void push_down(int id){
if(tree[id].l + 1==tree[id].r)return;
if(tree[id].y) {
tree[L(id)].y = max(tree[L(id)].y, tree[id].y);
tree[R(id)].y = max(tree[R(id)].y, tree[id].y);
}
}
void build(int l,int r,int id){
tree[id].l = l, tree[id].r = r; tree[id].mid = (l+r)>>1;
tree[id].y = 0;
if(l+1==r)return ;
build(l, tree[id].mid, L(id));
build(tree[id].mid, r, R(id));
}
void updata(int l,int r,int val,int id){
push_down(id);
if(l == tree[id].l && tree[id].r == r) {
tree[id].y = max(tree[id].y, val);
return ;
}
if(tree[R(id)].l<=l)
updata(l, r, val, R(id));
else if(r<=tree[L(id)].r)
updata(l, r, val, L(id));
else {
updata(l, tree[L(id)].r, val, L(id));
updata(tree[R(id)].l, r, val, R(id));
}
}
int query(int pos, int id){
push_down(id);
if(tree[id].l+1 == tree[id].r)
return tree[id].y;
if(tree[id].mid <= pos)
return query(pos, R(id));
else
return query(pos, L(id));
}
int x1[N], x2[N], y[N], n;
map<int,int>mp;
vector<int>G;
list<pair<int,int> >lis;
list<pair<int,int> >::iterator it1;
int hehex[N], hehey[N], top;
int main() {
int i;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while(~scanf("%d",&n)){
G.clear();
mp.clear();
for(i = 1; i <= n; i++){
scanf("%d %d %d",&y[i], &x1[i], &x2[i]);
G.push_back(x1[i]);
G.push_back(x2[i]);
}
sort(G.begin(), G.end());
G.erase(unique(G.begin(),G.end()), G.end());
for(i = 0; i <G.size(); i++) mp[G[i]] = i+1;
build(1, G.size(), 1);
for(i = 1; i <= n; i++)
updata(mp[x1[i]], mp[x2[i]], y[i], 1);
lis.clear();
for(i = 0; i < G.size(); i++) {
int tmp = query(i+1,1);
lis.push_back(pair<int,int>(G[i], tmp));
if(i+1<G.size())
lis.push_back(pair<int,int>(G[i+1], tmp));
}
for(it1 = lis.begin(); it1!=lis.end(); ) { int u = it1->second;
list<pair<int,int> >::iterator it2 = it1;
it2++; if(it2==lis.end())break;
list<pair<int,int> >::iterator it3 = it2;
it3++; if(it3==lis.end())break;
int v = it3->second;
if(u==v) {
lis.erase(it2);
continue;
}
it1++;
}
top = 0;
hehex[top] = G[0];
hehey[top++] = 0;
for(it1 = lis.begin(); it1 != lis.end(); it1++) {
hehex[top] = it1->first;
hehey[top++] = it1->second;
list<pair<int,int> >::iterator it2 = it1;
it2++;
if(it2 == lis.end())continue;
if(it1->first == it2->first)continue;
int u = it1->second, v = it2->second;
if(u>v)
hehex[top] = it1->first, hehey[top++] = v;
else if(u<v)
hehex[top] = it2->first, hehey[top++] = u;
}
it1 = lis.end(); it1--;
hehex[top] = it1->first, hehey[top++] = 0;
printf("%d\n", top);
for(i = 0; i < top; i++)
printf("%d %d\n",hehex[i], hehey[i]);
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Codeforces 35E Parade 扫描线 + list的更多相关文章
- Codeforces 35E Parade 扫描线
题意: 给出\(n\)个底边在\(x\)轴上的矩形,求外面的轮廓线顶点. 分析: 将每个矩形拆成两个事件:\(\\\{ l, y, + \\\}\)和\(\\\{ r, y, - \\\}\)分别表示 ...
- [Codeforces 35E] Parade
Link: Codeforces 35E 传送门 Brief Intro: 给定$n$个矩形,求出轮廓线的所有顶点 Solution: 对于此类可拆分成多个事件点的题目,使用扫描线的方式 将每个矩形分 ...
- Codeforces Beta Round #35 (Div. 2) E. Parade(扫描线)
题目链接 只要会做,周长并,这题肯定有思路. 有个小地方敲错了,细心啊,扫描线,有一段时间没写过了,还有注意排序的问题,很重要. #include <iostream> #include ...
- Codeforces 378B. Parade
B. Parade time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...
- CodeForces 733B Parade
B. Parade time limit per test1 second memory limit per test256 megabytes inputstandard input outputs ...
- 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)
原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解 By 岩之痕 目录: 一:综述 ...
- mark一下咕掉的题目
蒟蒻才普及组呀~ 大佬别D我 等集中补一下 CF980F:咋说捏,我觉得要联赛了做这题有点浪费时间,等想颓废了再来写写叭qwq 215E/279D/288E/331C3/431D/433E/750G/ ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 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 ...
随机推荐
- GAS Syntax
GAS or GNU as syntax is a different form of syntax for assembly language files, known also as AT& ...
- MySql的事务操作与演示样例
事务就是一个逻辑工作单元的一系列步骤. 事务是用来保证数据操作的安全性 事务的特征: Atomicity(原子性) Consistency(稳定性,一致性) Isolation(隔离性) Durabi ...
- 使用C#版本的gdal库打开hdf文件
作者:朱金灿 来源:http://blog.csdn.net/clever101 最近应同事的请求帮忙研究下使用C#版的gdal库读取hdf文件,今天算是有一点成果,特地做一些记录. 首先是编译C#版 ...
- mysql 查询重复 去除重复等等
查找所有重复标题的记录: SELECT * FROM t_info a WHERE ((SELECT COUNT(*) FROM t_info WHERE Title = a.Title) > ...
- POJ 1287 Networking (ZOJ 1372) MST
http://poj.org/problem?id=1287 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=372 和上次那题差 ...
- Hadoop基本原理之一:MapReduce 分类: A1_HADOOP 2014-08-17 19:26 1113人阅读 评论(0) 收藏
1.为什么需要Hadoop 目前,一块硬盘容量约为1TB,读取速度约为100M/S,因此完成一块硬盘的读取需时约2.5小时(写入时间更长).若把数据放在同一硬盘上,且全部数据均需要同一个程序进行处理, ...
- ArcGIS Engine 编辑- ITask
转自原文ArcGIS Engine 编辑- ITask 下面的代码是我们定制的一个工作流-给等高线赋值 namespace EngineApplication { [Guid("5b0c06 ...
- 【Bash百宝箱】Linux shell学习
shell特点-- Linux有多种shell能够使用,默认的为bash,bash有以下几个主要特点. 1.命令记忆能力 在命令行中按上下键能够找到一个前/后输入的命令.这些命令记录在-/.bash_ ...
- sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂)
sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂) 測试环境:sql 08, 08 R2, 2010, 2012, 2014 等 declare @agent t ...
- IT增值服务-客户案例(三):合肥薪火科技,Java和P2P网络借贷系统开发指导
客户整体情况: 合肥薪火科技,是安徽合肥一家主营微信开发和运营的中小企业,http://weimarket.cn/. 这家公司筹备.创立.曲折创业的经历,我一直有关注.因为2个老板,都是我的同学校友, ...