UVALive 7148 LRIP
LRIP
Time Limit: 10000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

解题:树分治
参考了Oyking大神的解法
我们用map<int,int>维护上升序列,first表示value,second表示长度,按first由小到大,second由大到小排列,因为在val相同的时候,当然是越长越好,但是,Oyking大神说过的冗余上升序列,意思就是在你的值比他小,长度也比它小,那么在拼接那个下降的序列的时候,就会导致极差大,所以可以删除这些没用的。
我们在搜索下降序列的时候,可以对map进行lower_bound,找出极差范围内最大的长度,进行合并即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
struct arc{
int to,next;
arc(int x = ,int y = -){
to = x;
next = y;
}
}e[maxn<<];
bool vis[maxn];
int head[maxn],val[maxn],D,ret,tot;
int sz[maxn],maxson[maxn];
map<int,int>up;
void add(int u,int v){
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
void dfs(int u,int fa){
sz[u] = ;
maxson[u] = ;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
dfs(e[i].to,u);
sz[u] += sz[e[i].to];
maxson[u] = max(maxson[u],sz[e[i].to]);
}
}
int FindRoot(int sum,int u,int fa){
int ret = u;
maxson[u] = max(maxson[u],sum - sz[u]);
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
int x = FindRoot(sum,e[i].to,u);
if(maxson[x] < maxson[ret]) ret = x;
}
return ret;
}
void dfs_down(int u,int fa,int len){
auto it = up.lower_bound(val[u] - D);
if(it != up.end()) ret = max(ret,it->second + + len);
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to] || val[e[i].to] < val[u]) continue;
dfs_down(e[i].to,u,len + );
}
}
void insert(int val,int len){
auto x = up.lower_bound(val);
if(x != up.end() && x->second >= len) return;
auto ed = up.upper_bound(val);
auto it = map<int,int>::reverse_iterator(ed);
while(it != up.rend() && it->second <= len) ++it;
up.erase(it.base(),ed);
up[val] = len;
}
void dfs_up(int u,int fa,int len){
insert(val[u],len);
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to] || val[e[i].to] > val[u]) continue;
dfs_up(e[i].to,u,len + );
}
}
void work(int u,vector<int>&son){
up.clear();
up[val[u]] = ;
for(int v:son){
if(val[v] >= val[u]) dfs_down(v,,);
if(val[v] <= val[u]) dfs_up(v,,);
}
}
void solve(int u){
dfs(u,);
int root = FindRoot(sz[u],u,);
vis[root] = true;
vector<int>son;
for(int i = head[root]; ~i; i = e[i].next)
if(!vis[e[i].to]) son.push_back(e[i].to);
work(root,son);
reverse(son.begin(),son.end());
work(root,son);
for(int i = head[root]; ~i; i = e[i].next)
if(!vis[e[i].to]) solve(e[i].to);
}
int main(){
int kase,n,u,v,cs = ;
scanf("%d",&kase);
while(kase--){
scanf("%d %d",&n,&D);
memset(head,-,sizeof head);
memset(vis,false,sizeof vis);
tot = ;
for(int i = ; i <= n; ++i)
scanf("%d",val + i);
for(int i = ret = ; i < n; ++i){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
solve();
printf("Case #%d: %d\n",cs++,ret);
}
return ;
}
UVALive 7148 LRIP的更多相关文章
- UVALive 7148 LRIP(树的分治+STL)(2014 Asia Shanghai Regional Contest)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...
- UVALive 7148 LRIP【树分治+线段树】
题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...
- UVALive 7148 LRIP 14年上海区域赛K题 树分治
题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及 ...
- LRIP UVALive - 7148 (点分治)
大意: 给定树, 每个点有点权, 求最长非减树链, 满足树链上最大值与最小值之差不超过D 点分治, 线段树维护最小值为$x$时的最长非增和非减树链即可. 实现时有技巧是翻转一下儿子区间, 这样可以只维 ...
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- 思维 UVALive 3708 Graveyard
题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...
- UVALive 6145 Version Controlled IDE(可持久化treap、rope)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
随机推荐
- python中函数参数
默认参数注意点 优点:灵活,当没有指定与形参对应的实参时就会使用默认参数 缺陷: 例子: >>> def h(m, l=[]): #默认参数时列 ...
- window上安装MySQL
一.安装MySQL 1.1 下载解压缩版的安装包,解压,然后配置环境变量 PATH=.......;D:\Program Files (x86)\mysql-5.5.27-win32\bin (注意是 ...
- vscode中将本地数据push至git repository
1.新建repository 2.本地写好的代码 3.执行git init 初始化git配置文件 4.提交已暂存文件 5.填写提交信息 6.执行push命令 7.完成
- Backbone.js之Todo源码浅析
相信每个接触了解过backbone的人都知道todo,网上的关于它的分析教程也都分析乱了.但是,知识只有自己学习领悟才是自己的,话不多说,正文开始. 在分析todo的源码之前,首先我们要知道todo具 ...
- 两个已排序数组的合并-C语言
最近在纸上写一个已排序数组的合并时,花了超过预期的时间.仔细想想,这种要放到毕业找工作那会两下就出来了,原因还在于工作后对基础没有重视,疏于练习. 说开一点,现在搜索引擎的发达确实给问题的解决带来了便 ...
- Proteus与Keil连接及其仿真(有例子哦!)
记录一下Proteus仿真的一些设置和使用,以方便自己以后复习和大家交流!如有错误,希望大家指正. 1.Proteus软件的安装,这里就不作说明了.
- 使用Recast.AI创建具有人工智能的聊天机器人
很多SAP顾问朋友们对于人工智能/机器学习这个话题非常感兴趣,也在不断思考如何将这种新技术和SAP传统产品相结合.Jerry之前的微信公众号文章C4C和微信集成系列教程曾经介绍了Partner如何利用 ...
- javaee 第六周作业
一.jsf(java server faces)的运行原理(工作方式) 1.jsf应用是事件驱动的,当一个事件发生时(比如用户单击一个按钮),事件通知通过HTTP发往服务器,服务器端使用叫做Faces ...
- SQLite -创建数据库
SQLite -创建数据库 SQLite sqlite3命令用于创建新的SQLite数据库.你不需要有任何特权来创建一个数据库. 语法: sqlite3命令的基本语法如下: $sqlite3 Data ...
- centos6上安装mysql8.0版本
本博客是采用yum源的方式安装,非常的方便和快捷.(redhat 与centos7 等操作系统都可以采用此方法,步骤大体一致) mysql官网地址: https://dev.mysql.com 开 ...