LRIP UVALive - 7148 (点分治)
大意: 给定树, 每个点有点权, 求最长非减树链, 满足树链上最大值与最小值之差不超过D
点分治, 线段树维护最小值为$x$时的最长非增和非减树链即可.
实现时有技巧是翻转一下儿子区间, 这样可以只维护一种树链, 时间复杂度$O(nlog^2n)$, 空间复杂度$O(n)$.
要注意使用线段树要注意每次清空, 不清空的话内存会卡到$O(nlog^2n)$
看其他dala0的题解好像说可以用set来维护, 但不是很懂要怎么用set区间更新最值.
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstdio>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <string.h>
#include <queue>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define pb push_back
#define mid ((l+r)>>1)
#define lc tr[o].l
#define rc tr[o].r
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
using namespace std; const int N = 1e5+10, INF = 0x3f3f3f3f;
int n, rt, sum, ans, D, tot, T;
int a[N], vis[N];
int mx[N], sz[N];
vector<int> g[N];
struct {
int l,r,mx;
} tr[N<<2]; void getrt(int x, int fa) {
mx[x]=0, sz[x]=1;
for (int y:g[x]) if (!vis[y]&&y!=fa) {
getrt(y,x);sz[x]+=sz[y];
mx[x]=max(mx[x],sz[y]);
}
mx[x]=max(mx[x],sum-sz[x]);
if (mx[rt]>mx[x]) rt=x;
} void query(int o, int l, int r, int ql, int qr, int c) {
if (!o) return;
if (ql<=l&&r<=qr) return ans = max(ans, tr[o].mx+c),void();
if (mid>=ql) query(ls,ql,qr,c);
if (mid<qr) query(rs,ql,qr,c);
}
void update(int &o, int l, int r, int x, int v) {
if (!o) o=++tot;
tr[o].mx = max(tr[o].mx, v);
if (l==r) return;
if (mid>=x) update(ls,x,v);
else update(rs,x,v);
} void dfs_lis(int x, int fa, int d) {
if (a[x]<a[fa]) return;
query(T,1,N,a[x]-D,a[x],1+d);
for (int y:g[x]) if (!vis[y]&&y!=fa) {
dfs_lis(y,x,d+1);
}
}
void dfs_lds(int x, int fa, int d) {
if (a[x]>a[fa]) return;
update(T,1,N,a[x],d);
for (int y:g[x]) if (!vis[y]&&y!=fa) {
dfs_lds(y,x,d+1);
}
}
void calc(int x, vector<int> &g) {
while (tot) tr[tot].l=tr[tot].r=tr[tot].mx=0,--tot;
T = 0;
update(T,1,N,a[x],0);
//因为题目要求非减, 一条链可能既是LIS又是LDS
//这里先用LIS更新答案, 再更新LDS的值, 防止一条链同时处理两次
//同时为了防止全部都为LDS的情况, 最后再用LDS更新一次答案
//但是实际上本题数据比较水, 很多情况不考虑也能过
for (int y:g) {
dfs_lis(y,x,1);
dfs_lds(y,x,1);
}
query(T,1,N,a[x]-D,a[x],1);
}
void solve(int x) {
vis[x] = 1;
vector<int> son;
for (int y:g[x]) son.pb(y);
calc(x,son);
reverse(son.begin(),son.end());
calc(x,son);
for (int y:g[x]) if (!vis[y]) {
mx[rt=0]=n,sum=sz[y];
getrt(y,0),solve(rt);
}
} void work() {
scanf("%d%d", &n, &D);
REP(i,1,n) scanf("%d", a+i);
REP(i,1,n) g[i].clear(),vis[i]=0;
REP(i,2,n) {
int u, v;
scanf("%d%d", &u, &v);
g[u].pb(v),g[v].pb(u);
}
sum=mx[0]=n, getrt(1,0), solve(rt);
}
int main() {
int t;
scanf("%d", &t);
REP(i,1,t) {
ans = 1;
work();
printf("Case #%d: %d\n", i, ans);
}
}
LRIP UVALive - 7148 (点分治)的更多相关文章
- 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出发不降路径的长度,以及 ...
- UVALive 7148 LRIP
LRIPTime Limit: 10000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu 解题:树分治 参考了Oyking大神的解法 ...
- UvaLive 6667 Longest Chain (分治求三元组LIS&树状数组)
题目链接: here 题意: 和hdu4742类似.差别就是一部分三元组是直接给出的.另一部分是用他给的那个函数生成的.还有就是这里的大于是严格的大于a>b必须ax>bx,ay>by ...
- <算法竞赛入门经典> 第8章 贪心+递归+分治总结
虽然都是算法基础,不过做了之后还是感觉有长进的,前期基础不打好后面学得很艰难的,现在才慢慢明白这个道理. 闲话少说,上VOJ上的专题训练吧:http://acm.hust.edu.cn/vjudge/ ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- 树分治learning
学习了树的点分治,树的边分治似乎因为复杂度过高而并不出众,于是没学 自己总结了一下 有些时候面对一些树上的结构 并且解决的是和路径有关的问题的时候 如果是多个询问 关注点在每次给出两个点,求一些关于这 ...
- 算法笔记--CDQ分治 && 整体二分
参考:https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 前置技能:树 ...
随机推荐
- Yii 获取url 的一些方法
原文出处http://blog.csdn.net/iefreer/article/details/21325371 1. 获取url中的host信息: Yii::app()->request-& ...
- 麦子学院bootstrap实战项目官网,后台,jquery.singlePageNav.min.js ,wow.min.js,animate.css使用
1.源码笔记 我的源码+笔记(很重要):链接: https://pan.baidu.com/s/1eSxgLV0 密码: 2pi2 感谢麦子学院项目相关视频:链接: https://pan.baidu ...
- avaScript 的基础学习(一)
JavaScript概述 JavaScript由三部分组成: JavaScript的基础 JS的引入方式: JS的数据类型: 运算符: 流程控制: JavaScript的对象 BOM对象 DOM Ev ...
- 洛谷P1736 创意吃鱼法 dp
正解:dp 解题报告: 早就想写dp的题目辣!我发现我的dp好差啊QAQ所以看到列表的小朋友写dp的题目就跟着他们的步伐做下题好辣QwQ 这题的话没有那——么难,大概说下趴QwQ 首先说下题意 前面一 ...
- android的selector选择器
1. drawable/actionbar_compat_item.xml 2.drawable/actionbar_compat_item_pressed.xml 3.drawable/action ...
- React Native专题-江清清
本React Native讲解专题:主要讲解了React Native开发,由基础环境搭建配置入门,基础,进阶相关讲解. 刚创建的React Native交流8群:533435865 欢迎各位大牛, ...
- glassfish3新建domain
下载路径:http://download.oracle.com/glassfish/3.1.2.2/release/index.html .zip (解压缩)cd /glassfish3/glassf ...
- Java转Exe
1.Jsmooth Java文件打包成exe文件(可以在没安装JDK的环境下运行):http://www.tuicool.com/articles/byIFJn 2.用JSmooth制作java ja ...
- #C++初学记录(高精度运算)(加法)
高精度运算 不管是int还是double亦或者long long ,这些定义变量都有数据范围的一定限制,在计算位数超过十几位的数,也就是超过他们自身的数据范围时,不能采用现有类型进行计算,只能自己通过 ...
- Keras实践:模型可视化
Keras实践:模型可视化 安装Graphviz 官方网址为:http://www.graphviz.org/.我使用的是mac系统,所以我分享一下我使用时遇到的坑. Mac安装时在终端中执行: br ...