主题链接:点击打开链接

意甲冠军:特定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. Android学习笔记(20):时钟(AnalogClock和TextClock)和计时器(Chronometer)

    时钟文本TextClock继承自TextView.是用于显示当前时间的文本框. TextClock支持的XML属性和相关方法 XML属性 相关方法 说明 android:format12Hour se ...

  2. cmder显示UTF-8字体

    https://blog.csdn.net/x_iya/article/details/50627829 WIN+ALT+P打开配置 搜索chcp chcp 65001

  3. JS实现页面table鼠标移动改变tr行颜色,单击tr选中复选框功能

    JS源代码: //需要设置tr背景颜色 var highlightcolor='#bfecfc'; //设置背景颜色 function changeto(index){ var tr1 = docum ...

  4. [Angular] Using NO_ERRORS_SCHEMA

    For example, when testing container component we might import lots of children components, but we di ...

  5. IAdjustCountOption--动态设置recycleView的itemCount(不须要改动数据源)

    概述 RecycleViewUtil是新增的一个主要针对RecycleView的一个工具类.该工具类中提供了部分RecycleView可能会使用到的方法,当中也包含了一些用来增强HeaderRecyc ...

  6. ServerSocketChannel API用法

    java.nio.channels 类 ServerSocketChannel java.lang.Object java.nio.channels.spi.AbstractInterruptible ...

  7. 【22.17%】【codeforces718B】 Efim and Strange Grade

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...

  8. [自学AndroidStudio系列]第二篇章:高速上手AS小技巧其一

    事实上看过第一篇的文章的人可能发现了,这个系列实际上是针对,有android开发经验的,之前使用Eclipse的开发人员;所以,避免无谓的口舌,直接进入说重点吧; 关闭项目自己主动打开 AS会自己主动 ...

  9. 【hdu 1536】S-Nim

    Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  10. [Flow] Declare types for application

    In Flow, you can make global declarion about types. Run: flow init It will generate .flowconfig file ...