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_ ...
随机推荐
- awr 收集时间
windows 收集 awr 报告,一分钟一个.
- Unity项目学习笔记
1.TCP和IP IP:主要作用是在复杂的网络环境中将数据包发送给的最终的目标地址. 端口号:系统会分给系统端口号 一般知名的端口号在0-1023之间,而我们经常使用的自定义/动态分配的端口号则一般 ...
- AJPFX:求两个城市之间的距离
键盘录入多个城市: 城市1,城市2,城市3 以 ### 结束输出然后再键盘录入各个城市之间的距离: 格式如下:0,12,4512,0,2245,22,0### 然后按照输入的两个城市,求得两个城市 ...
- 洛谷P2774 方格取数问题(最小割)
题意 $n \times m$的矩阵,不能取相邻的元素,问最大能取多少 Sol 首先补集转化一下:最大权值 = sum - 使图不连通的最小权值 进行黑白染色 从S向黑点连权值为点权的边 从白点向T连 ...
- 51nod 1417 天堂里的游戏
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 多年后,每当Noder看到吉普赛人,就会想起那个遥远的下午. Noder躺在草地上漫无目的的张望,二 ...
- 推荐一个有趣的Chrome扩展程序-查看任意网站的开发技术栈
对于前端开发人员来说,目前的前端框架层出不穷,最受欢迎的莫过于所谓的前端框架三驾马车:Angular, React和Vue.在学习的过程中,肯定好奇现在的互联网公司的网站用的何种前端框架来开发的. C ...
- Unity Shader-热空气扭曲效果
GrabPass GrabPass是Unity为我们提供的一个很方便的功能,可以直接将当前屏幕内容渲染到一张贴图上,我们可以直接在shader中使用这张贴图而不用自己去实现渲染到贴图这样的一个过程,大 ...
- python 网络编程篇
基础模拟通话网络程序: #客户端 import socket client = socket.socket() client.connect(('localhost',6969)) client.se ...
- ES6对象和数组解构
解构可以避免在对象赋值时再生成多余的中间变量: function foo() { return [1,2,3]; } let arr = foo(); // [1,2,3] let [a, b, c] ...
- 服务器禁用ping
linux禁ping.这里操作的是centos6.5内核参数禁ping禁用ping #echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all启用ping ...