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 ...
随机推荐
- js中退出语句break,continue和return 比较 (转)
在 break,continue和return 三个关键字中, break,continue是一起的,return 是函数返回语句,但是返回的同时也将函数停止 首先:break和continue两个一 ...
- java I/O库的设计模式
在java语言 I/O库的设计中,使用了两个结构模式,即装饰模式和适配器模式. 在任何一种计算机语言中,输入/输出都是一个很重要的部分.与一般的计算机语言相比,java将输入/输出的功能和使 ...
- 关于stm32的RAM大小
- position:relative和position:absolute的差别及使用方法
这几天在做项目时遇到做选项卡的功能时,标题和内容区域的背景颜色不同.且须要选到当前标题时,此标题以下会出现下边框及小三角边框,这样就会超出标题背景颜色需覆盖以下内容区域.这时就须要用到potition ...
- ios开发图层layer与核心动画二:CATransform3D,CAlayear和UIView区别,layer的position和anchorpoint
一:CATransform3D #import "ViewController.h" @interface ViewController () @property (weak, n ...
- Xcode6 模拟器路径
Xcode6公布后,出现了非常多的变动,功能性的变动,在这里不进行过多的赘述,在WWDC上苹果已经进行了讲述,网上也有非常多文章,这里要介绍的是一些不太easy发现的,但非常重要的小地方. ...
- [GraphQL] Add an Interface to a GraphQL Schema
As we start building out more complex GraphQL schemas, certain fields start to repeat across differe ...
- xCode中怎样保存自己的代码块
在开发iOS的过程中.xCode肯定是用得最多的工具.没有之中的一个.由于苹果官方提供的就这一个平台,尽管没有竞争对手,但秉承苹果一贯的注重细节的原则,xCode还是一款相当不错的IDE. 作为一名i ...
- 小强的HTML5移动开发之路(27)—— JavaScript回顾2
Javascript面向对象基础知识 1.如何定义一个类,使用如下语法来创建一个类 function Person(name, age){ //习惯上第一个字母大写 //this修饰的变量称为属性 t ...
- 对raid几个技术的简单理解
磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有冗余能力的阵列”之意,主要体现在两方面: 1.HA 高可用性,也就是冗余 2.L ...