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_ ...
随机推荐
- Linux、Windows 下分割、合并rar文件
1.分割rar 1.1 linux下分割压缩rar 安装rar和unrar和序 $sudo aptitude install rar unrar 示例,分割压缩temp文件,每个包为1MB $rar ...
- JavaEE中一些缩写的含义
EJB:Enterprise JavaBeans (企业JavaBeans) XML:Extensible Markup Lauguage (可扩展标记语言) SOAP:Simple Object ...
- Unity中所有特殊的文件夹
1. 隐藏文件夹以.开头的文件夹会被Unity忽略.在这种文件夹中的资源不会被导入,脚本不会被编译.也不会出现在Project视图中.2. Standard Assets在这个文件夹中的脚本最先被编译 ...
- 非常强大的前端插件:emmet
安装 Emmet 也有快速生成文件头的功能啊,而且更强大啊输入下边加粗的缩写,然后Tab,就OK了啊http://docs.emmet.io/cheat-sheet/ html:4t <!DOC ...
- 进度条--ProgressBar和BackgroundWorker
1) 需求:就餐打卡数据处理后,插入数据库中,用进度条显示过程 2) 思路:总进度为txt文本文件的行数(数据都是按照行写入),文本文件的大小 //BackgroundWorker对象有三个主要的事件 ...
- Git之删除本地和远程项目
目录 删除本地项目 删除远程项目 删除本地项目: git rm -rf project 或者 rm -rf project [删除工作区项目] git add project [将删除的项目添加 ...
- 获取当前目录 文件输出html 网页查看
@echo off setlocal set LISTFILE=list.html echo MAKING LISTFILE … (PLEASE WAIT) echo ^<!doctype ht ...
- 洛谷 P2788 数学1(math1)- 加减算式
题目背景 蒟蒻HansBug在数学考场上,挠了无数次的头,可脑子里还是一片空白. 题目描述 好不容易啊,HansBug终于熬到了做到数学最后一题的时刻了,眼前是一堆杂乱的加减算式.显然成功就在眼前了. ...
- Web开发者不容错过的10个HTML5工具
HTML5已经成为当今世界的一个必然组成部分.由于World Wide Web万维网是使用超文本标记语言来架构和呈现的,于是HTML5成为了最流行的编程语言之一.随着网络的不断扩张,Web开发人员非常 ...
- mysql 增删查改
非关系型数据库关系型数据库Oracle mysql sqlserver db2 Postgresql Sqlite access sqlserver 微软db2 ibm================ ...