主题链接:点击打开链接

意甲冠军:特定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. 黑马day18 jquery高级特性&amp;Ajax的load方法

    介绍jquery中的load方法: (1).前面没有jquery.修饰,能够判断出他是一个普通的非全局函数(也就是说是一个局部函数):$.,$().,jquery.等修饰的就是全局函数.没有这些修饰的 ...

  2. Android系统开发(1)——GCC编译器的编译和安装过程

    GCC编译器介绍 GCC编译器(GNG C Compiler)是GNU项目中符合ANSI C标准的编译系统,能够编译C  C++  Object C等语言编写的程序,同时GCC也是一个交叉编译器,特别 ...

  3. Spring boot(一) 入门

    本系列基于Eclipse 4.7 .JDK 8 一.下载STS (1)STS 注意自己的eclipse版本. 在 Update Site Archives 里面选择对应eclipse的版本下载. (2 ...

  4. Jcaptca 图片

    http://www.oschina.net/code/snippet_89964_6009 http://blog.csdn.net/tender001/article/details/846969 ...

  5. Drupal 7 模块开发 建立模块帮助信息(hook_help)

    建立模块请參考 <Drupal 7 模块开发 建立> 假设你要支持中文,文件格式必须保存为 UTF-8.NO BOM ------------------------------ hook ...

  6. iOS开发之Quartz2D 二:绘制直线,曲线,圆弧,矩形,椭圆,圆

    #import "DrawView.h" @implementation DrawView /** * 作用:专门用来绘图 * 什么时候调用:当View显示的时候调用 * @par ...

  7. eclipse 远程debug tomcat web项目

    1.首先须要在linux系统tomcat/bin文件夹下配置catalina.sh这个文件里添加: CATALINA_OPTS="-Xdebug  -Xrunjdwp:transport=d ...

  8. STL map 按key值和按value值排序

    map是用来存放<key, value>键值对的数据结构,能够非常方便高速的依据key查到对应的value. 假如存储水果和其单位价格.我们用map来进行存储就是个不错的选择. 我们这样定 ...

  9. 第二篇:_UICascadingTextStorage attributesAtIndex:effectiveRange:]: Range or index out of bounds

    注意下文标红字段: #pragma mark- 输入改变时 - (void) textFieldDidChanged:(UITextField *) TextField{ //搜索关键字一旦改变,将重 ...

  10. Android EditText文本内容变化监听方法

    package com.google; import android.app.Activity; import android.os.Bundle; import android.text.Edita ...