大意: 给定树, 每个点有点权, 求最长非减树链, 满足树链上最大值与最小值之差不超过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 (点分治)的更多相关文章

  1. UVALive 7148 LRIP(树的分治+STL)(2014 Asia Shanghai Regional Contest)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...

  2. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  3. UVALive 7148 LRIP 14年上海区域赛K题 树分治

    题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及 ...

  4. UVALive 7148 LRIP

    LRIPTime Limit: 10000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu 解题:树分治 参考了Oyking大神的解法 ...

  5. UvaLive 6667 Longest Chain (分治求三元组LIS&amp;树状数组)

    题目链接: here 题意: 和hdu4742类似.差别就是一部分三元组是直接给出的.另一部分是用他给的那个函数生成的.还有就是这里的大于是严格的大于a>b必须ax>bx,ay>by ...

  6. <算法竞赛入门经典> 第8章 贪心+递归+分治总结

    虽然都是算法基础,不过做了之后还是感觉有长进的,前期基础不打好后面学得很艰难的,现在才慢慢明白这个道理. 闲话少说,上VOJ上的专题训练吧:http://acm.hust.edu.cn/vjudge/ ...

  7. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  8. 树分治learning

    学习了树的点分治,树的边分治似乎因为复杂度过高而并不出众,于是没学 自己总结了一下 有些时候面对一些树上的结构 并且解决的是和路径有关的问题的时候 如果是多个询问 关注点在每次给出两个点,求一些关于这 ...

  9. 算法笔记--CDQ分治 && 整体二分

    参考:https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 前置技能:树 ...

随机推荐

  1. 焦作网络赛L-Poor God Water【矩阵快速幂】

    God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...

  2. 【ArcGIS for JavaScript api】Clusterlayer聚簇类

    1.作用: 聚簇类是用于前端显示优化,使POI点要素显示更为美观.大量的Marker距离太近会引起压盖而对浏览或者操作产生不便,因此,一般在超过1K点的时候,用此类.. 2.使用方式: 1: // c ...

  3. C# WinForm实现任务栏程序图标闪烁

    相信大家在用QQ的时候都会知道,你打开了QQ聊天窗口,如果窗口不是当前激活的窗口的话,收到QQ消息时,任务栏(不是托盘图标)上的图标会闪一下变成黄色(Win7默认主题下),用以通知用户有消息进来了,之 ...

  4. Highway Project---zoj3946(最短路SPFA)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5718 题意: 有n个点 m(n,m<=10^5)条路,现在要建 ...

  5. 【我的Android进阶之旅】解决AndroidStudio编译时报错:Timeout waiting to lock artifact cache .

    1. 错误描述 今天在Android Studio中,使用gradle命令的时候,出现了如下所示的错误: D:\GitLab Source\XTCLint>gradlew clean uploa ...

  6. [随感]GIS开发的困惑

    从事GIS应用开发也有3年了,但是做了些东西自己始终不满意,不是不稳定就是效率低,不是功能杂就是不实用! 首先是AE开发,我必须说自己很欣赏ArcGIS的软件设计架构和思想.但是在开发的过程中也确实遇 ...

  7. django高级之点赞、文章评论及上传文件

    目录: 点赞 文章评论 上传文件 保留页面条件 一.点赞 1.所用技术: django model F查询 js应用:$(function () {}); 为文件加载完成执行ready() 方法.等同 ...

  8. 用Python实现的数据结构与算法:队列

    一.概述 队列(Queue)是一种先进先出(FIFO)的线性数据结构,插入操作在队尾(rear)进行,删除操作在队首(front)进行. 二.ADT 队列ADT(抽象数据类型)一般提供以下接口: Qu ...

  9. Mybatis分页查询与动态SQL

    一.Mybatis的分页查询 由于第一二节较为详细讲述了Mybatis的环境搭建,文件配置,SQL编写和Java代码实现,所以接下来的讲述都将只抽取关键代码和mapper文件中的关键sql,详细的流程 ...

  10. svn命令行使用

    1.将文件checkout到本地目录    svn checkout path(path是服务器上的目录)    例如:svn checkout svn://192.168.1.1/pro/domai ...