主题链接:点击打开链接

意甲冠军:特定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的更多相关文章

  1. Codeforces 35E Parade 扫描线

    题意: 给出\(n\)个底边在\(x\)轴上的矩形,求外面的轮廓线顶点. 分析: 将每个矩形拆成两个事件:\(\\\{ l, y, + \\\}\)和\(\\\{ r, y, - \\\}\)分别表示 ...

  2. [Codeforces 35E] Parade

    Link: Codeforces 35E 传送门 Brief Intro: 给定$n$个矩形,求出轮廓线的所有顶点 Solution: 对于此类可拆分成多个事件点的题目,使用扫描线的方式 将每个矩形分 ...

  3. Codeforces Beta Round #35 (Div. 2) E. Parade(扫描线)

    题目链接 只要会做,周长并,这题肯定有思路. 有个小地方敲错了,细心啊,扫描线,有一段时间没写过了,还有注意排序的问题,很重要. #include <iostream> #include ...

  4. Codeforces 378B. Parade

    B. Parade time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  5. CodeForces 733B Parade

    B. Parade time limit per test1 second memory limit per test256 megabytes inputstandard input outputs ...

  6. 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)

    原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解    By 岩之痕 目录: 一:综述 ...

  7. mark一下咕掉的题目

    蒟蒻才普及组呀~ 大佬别D我 等集中补一下 CF980F:咋说捏,我觉得要联赛了做这题有点浪费时间,等想颓废了再来写写叭qwq 215E/279D/288E/331C3/431D/433E/750G/ ...

  8. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  9. 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 ...

随机推荐

  1. 用css3解决移动端页面自适应横屏竖屏的思考

    之前对于横屏的webapp做过一些尝试,可是始终不是非常好的解决方式,前段时间又接触了类似的需求,尝试了感觉更好的解决方式. 之前的方法写的博客:移动网页横竖屏兼容适应的一些体会 这里举的样例还是平时 ...

  2. 段的创建表user_segments 分类: H2_ORACLE 2013-08-10 11:13 714人阅读 评论(0) 收藏

    1.段的定义及类型 Oracle中的段(segment)是占用磁盘空间的一个对象,最常见的段类型包括: l  聚簇cluster l  表table l  表分区 tablepartition l  ...

  3. windows server 2012 AD 活动目录部署加入域并创建域用户(寻找视频课程)(计算机加入域其实是本计算机的管理员账号(本机名)加入域,关联账号即可在已经加入域的计算机上面登录)

    windows server 2012 AD 活动目录部署加入域并创建域用户(寻找视频课程)(计算机加入域其实是本计算机的管理员账号(本机名)加入域,关联账号即可在已经加入域的计算机上面登录) 一.总 ...

  4. 【23.58%】【code forces 321E】Ciel and Gondolas

    time limit per test4 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  5. Strut2与Hibernate的一个web分页功能

    代码没有进行过多的封装,可能看起来有点action代码部分,hibernate在这里只起到了一个查询记录集的作用. import java.util.ArrayList; import java.ut ...

  6. html5-8 如何控制html5中的视频标签和音频标签

    html5-8 如何控制html5中的视频标签和音频标签 一.总结 一句话总结:找到视频或者音频的element对象,然后查手册看对应的方法或者属性就可以,里面有控制的. 1.如何控制html5中的视 ...

  7. Request对象和Response对象详解

    Request 1.获取请求的基本信息 1>获取请求的url和uri 2>获取url后面的请求参数部分的字符串 3>获取请求方式 4>获取主机名,IP地址 5>获取 Co ...

  8. 诊断并解决CentOS SSH连接慢的方法

    诊断并解决CentOS SSH连接慢的方法: http://os.51cto.com/art/201507/484743.htm

  9. iOS云存储:CloudKit 基本使用教程 增删改查(Swift)

    一.从iOS8开始,苹果为开发者提供了ClouKit,可以把我们的应用程序和用户数据存储在iCloud上,用于代替后台服务器,开发移动代码即可. 二.设置 (1)需要一个开发者账号,并且设置一个bun ...

  10. phpstorm常用快捷键有哪些(图解归类)

    phpstorm常用快捷键有哪些(图解归类) 一.总结 一句话总结: 10.方法参数提示,显示默认参数   解答:--------CTRL+P 13.显示类层级关系图,继承/实现关系   解答:--- ...