269D
扫描线+dp
先对坐标排序,然后·用set维护端点,每次插入左端点,扫描到右端点时删除。每次考虑新插入时分割了哪两个木板,自己分别连边,再删除原来的边,最后dp(好像得维护used,有环)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = , inf = ;
struct data {
int l, r, h;
data(int l = , int r = , int h = ) : l(l), r(r), h(h) {}
} ed[N];
int n, t, cnt;
int dp[N], used[N];
PII e[N];
set<PII> s, m;
vector<PII> G[N];
void dfs(int u)
{
if(dp[u] == inf || used[u]) return;
used[u] = ;
for(int i = ; i < G[u].size(); ++i)
{
PII x = G[u][i];
int v = x.first, w = x.second;
dfs(v);
dp[u] = max(dp[u], min(dp[v], w));
}
}
int main()
{
scanf("%d%d", &n, &t);
for(int i = ; i <= n; ++i)
{
int h, l, r; scanf("%d%d%d", &h, &l, &r);
ed[i] = data(l, r, h);
e[++cnt] = make_pair(l, i);
e[++cnt] = make_pair(r, -i);
}
sort(e + , e + cnt + );
ed[n + ] = data(-inf, inf, );
ed[n + ] = data(-inf, inf, t);
s.insert(make_pair(, n + ));
s.insert(make_pair(t, n + ));
for(int i = ; i <= cnt; ++i)
{
int x = e[i].second;
if(x < )
{
s.erase(make_pair(ed[-x].h, -x));
continue;
}
PII t = make_pair(ed[x].h, x);
set<PII> :: iterator it = s.lower_bound(t);
PII up = *it;
--it;
PII low = *it;
m.erase(make_pair(up.second, low.second));
m.insert(make_pair(up.second, x));
m.insert(make_pair(x, low.second));
s.insert(t);
}
for(set<PII> :: iterator it = m.begin(); it != m.end(); ++it)
{
PII x = *it;
int len = min(ed[x.second].r, ed[x.first].r) - max(ed[x.second].l, ed[x.first].l);
G[x.second].push_back(make_pair(x.first, len));
}
dp[n + ] = inf;
dfs(n + );
printf("%d\n", dp[n + ]);
return ;
}
线段树维护+dp
这个方法好恶心,调了好长时间,边界搞错。
先离散化坐标,然后按高度排序,正反两次建边。但是一定要注意,边界很恶心,有可能出现1-2,2-3这样的,这样是不相交的。所以右端点要-1就避免了这种情况,因为如果原先只有1单位重合,那么现在不相交了。如果有1单位以上重合,那么现在还是相交的。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int M = , inf = ;
int n, T, N;
vector<PII> G[M];
vector<int> v;
map<int, int> mp, mir;
int dp[M], used[M];
struct data {
int l, r, h;
} a[M];
struct seg {
int tree[M << ], tag[M << ];
void pushdown(int x)
{
if(!tag[x]) return;
tag[x << ] = tag[x];
tag[x << | ] = tag[x];
tree[x << ] = tag[x];
tree[x << | ] = tag[x];
tag[x] = ;
}
void update(int l, int r, int x, int a, int b, int c)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
tree[x] = tag[x] = c;
return;
}
pushdown(x);
int mid = (l + r) >> ;
update(l, mid, x << , a, b, c);
update(mid + , r, x << | , a, b, c);
tree[x] = max(tree[x << ], tree[x << | ]);
}
int query(int l, int r, int x, int a, int b)
{
if(l > b || r < a) return ;
if(l >= a && r <= b) return tree[x];
pushdown(x);
int mid = (l + r) >> ;
return max(query(l, mid, x << , a, b), query(mid + , r, x << | , a, b));
}
} t;
void construct(int N, bool flag)
{
memset(t.tree, , sizeof(t.tree));
memset(t.tag, , sizeof(t.tag));
for(int i = ; i < n; ++i)
{
int k = t.query(, N, , a[i].l, a[i].l);
int low = max(a[i].l, a[k].l), high = min(a[i].r, a[k].r), len = mir[high] - mir[low];
int tt = t.query(, N, , low, high - );
if(tt == k && tt)
{
if(!flag) G[k].push_back(make_pair(i, len));
else G[n - i + ].push_back(make_pair(n - k + , len));
}
k = t.query(, N, , a[i].r - , a[i].r - );
low = max(a[i].l, a[k].l), high = min(a[i].r, a[k].r), len = mir[high] - mir[low];
tt = t.query(, N, , low, high - );
if(tt == k && tt)
{
if(!flag) G[k].push_back(make_pair(i, len));
else G[n - i + ].push_back(make_pair(n - k + , len));
}
t.update(, N, , a[i].l, a[i].r - , i);
}
}
void dfs(int u)
{
if(used[u] || dp[u] == inf) return;
used[u] = ;
for(int i = ; i < G[u].size(); ++i)
{
PII x = G[u][i];
int v = x.first, w = x.second;
dfs(v);
dp[u] = max(dp[u], min(dp[v], w));
}
}
bool cp(data x, data y)
{
return x.h == y.h ? x.l < y.l : x.h < y.h;
}
int main()
{
scanf("%d%d", &n, &T);
a[].h = ;
a[n + ].h = T;
a[].l = a[n + ].l = -inf;
a[].r = a[n + ].r = inf;
v.push_back(inf);
v.push_back(-inf);
for(int i = ; i <= n; ++i)
{
scanf("%d%d%d", &a[i + ].h, &a[i + ].l, &a[i + ].r);
v.push_back(a[i + ].l);
v.push_back(a[i + ].r);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
N = v.size();
for(int i = ; i < v.size(); ++i)
{
mp[v[i]] = i + ;
mir[i + ] = v[i];
}
n += ;
for(int i = ; i <= n; ++i)
{
a[i].l = mp[a[i].l];
a[i].r = mp[a[i].r];
}
sort(a + , a + n + , cp);
construct(N, false);
reverse(a + , a + n + );
construct(N, true);
dp[n] = inf;
dfs();
printf("%d\n", dp[]);
return ;
}
269D的更多相关文章
- 269D Maximum Waterfall
传送门 题目大意 给出一些墙,水从高往低流,每次只能到达一面墙,选择一个路径,使得路径上的流量的最小值最大. 分析 这是一道经典的扫描线题,我们发现能够合法的线段对数至多只有n对.将一条线段拆成两个点 ...
- PLSQL_Oracle Exception异常分类、异常抛出、异常处理、异常传播(概念)
2014-06-03 Created By BaoXinjian
- javaWeb面试题(重要)
1.Javaweb 技术的结构 1.1 技术结构图
随机推荐
- [入门指南]-技术学习-Ebean
占坑 官网
- Tomcat8 连接池
1.所有的tomcat项目共用一个连接池配置 1.1 修改conf->context.xml文件,在Context节点下配置 <Resource name="jdbc/myDat ...
- div+css 组织结构
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>家谱 ...
- 谈一谈Dijkstra
dijkstra呢是最短路三大算法之一.很多人都觉得不如spfa,但是这两者在跑稠密图时,dijkstra有奇效 在讲之前先说一说食用方法: 适用于有向的无负权值的图. 样例飘过 6 9 1 //n个 ...
- Django基础配置
安装djangopip install Django==1.11.4进入pythonimport django查看版本号django.get_version()创建项目,在合适位置创建一个目录进入你要 ...
- 百度搜索引擎关键字URL采集爬虫优化行业定投方案高效获得行业流量-代码篇
需要结合:<百度搜索引擎关键字URL采集爬虫优化行业定投方案高效获得行业流量--笔记篇> 一起看. #!/user/bin/env python # -*- coding:utf-8 -* ...
- WEB 移动端 CSS3动画性能 优化
很多时候,我们在开发移动端的时候要使自己的网页兼容不同的机型,很多时候会采用CSS3动画,但是很多时候在安卓机下,动画明显会出现卡顿,很难看,那么这里我介绍几个CSS 属性进行硬件加速那么就会得到明显 ...
- CodeForcesGym 100735B Retrospective Sequence
Retrospective Sequence Time Limit: Unknown ms Memory Limit: 65536KB This problem will be judged on C ...
- FOJ2250 不可能弹幕结界
Problem 2250 不可能弹幕结界 Time Limit: 1000 mSec Memory Limit : 65536 KB Problem Description 咲夜需要穿过一片弹幕 ...
- springboot优雅的关闭应用
使用actuator,通过发送http请求关闭 将应用注册为linux服务,通过service xxx stop关闭 具体这两种方式如何实现,这里就不说了,网上百度一堆,主要讲一下在这两种情况下web ...