BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树

BZOJ 2588 Count on a tree

题面

求树上两点之间路径上第k大的点权。

题解

一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死……

然后发现,如果每个点都挂一棵主席树,每棵都通过修改父亲的主席树得到,这样当询问路径(u, v)时,u的主席树+v的主席树-lca的主席树-fa[lca]的主席树就得到了路径上的主席树。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){char c;bool op = 0;while(c = getchar(), c < '0' || c > '9')if(c == '-') op = 1;x = c - '0';while(c = getchar(), c >= '0' && c <= '9')x = x * 10 + c - '0';if(op) x = -x;
}
template <class T>
void write(T x){if(x < 0) putchar('-'), x = -x;if(x >= 10) write(x / 10);putchar('0' + x % 10);
}const int N = 100005, M = 3000005;
int n, m, a[N], lst[N], tot, ans;
int ecnt, adj[N], nxt[2*N], go[2*N];
int fa[N], dep[N], lg[2*N], seq[2*N], cnt, pos[N], mi[2*N][20];
int idx, root[N], data[M], ls[M], rs[M];void add(int u, int v){go[++ecnt] = v;nxt[ecnt] = adj[u];adj[u] = ecnt;
}
void dfs(int u, int pre){fa[u] = pre, dep[u] = dep[pre] + 1;seq[++cnt] = u, pos[u] = cnt;for(int e = adj[u], v; e; e = nxt[e])if(v = go[e], v != pre)dfs(v, u), seq[++cnt] = u;
}
int Min(int a, int b){return dep[a] < dep[b] ? a : b;
}
void init(){for(int i = 1, j = 0; i <= cnt; i++){lg[i] = i == (1 << (j + 1)) ? ++j : j;mi[i][0] = seq[i];}for(int j = 1; (1 << j) <= cnt; j++)for(int i = 1; i + (1 << j) - 1 <= cnt; i++)mi[i][j] = Min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
}
int getlca(int u, int v){int l = pos[u], r = pos[v];if(l > r) swap(l, r);int j = lg[r - l + 1];return Min(mi[l][j], mi[r - (1 << j) + 1][j]);
}
void build(int &k, int l, int r){k = ++idx;if(l == r) return;int mid = (l + r) >> 1;build(ls[k], l, mid);build(rs[k], mid + 1, r);
}
void change(int old, int &k, int l, int r, int p){k = ++idx;data[k] = data[old] + 1, ls[k] = ls[old], rs[k] = rs[old];if(l == r) return;int mid = (l + r) >> 1;if(p <= mid) change(ls[old], ls[k], l, mid, p);else change(rs[old], rs[k], mid + 1, r, p);
}
int query(int u, int v, int x){int lca = getlca(u, v), l = 1, r = n, mid, sum;int k[4] = {root[u], root[v], root[lca], root[fa[lca]]};while(l < r){mid = (l + r) >> 1, sum = data[ls[k[0]]] + data[ls[k[1]]] - data[ls[k[2]]] - data[ls[k[3]]];if(x <= sum){r = mid;for(int i = 0; i < 4; i++) k[i] = ls[k[i]];}else{l = mid + 1, x -= sum;for(int i = 0; i < 4; i++) k[i] = rs[k[i]];}}return lst[l];
}
void build_tree(){build(root[0], 1, tot);static int que[N], qr;que[qr = 1] = 1;for(int ql = 1; ql <= qr; ql++){int u = que[ql];change(root[fa[u]], root[u], 1, n, a[u]);for(int e = adj[u], v; e; e = nxt[e])if(v = go[e], v != fa[u])que[++qr] = v;}
}
int main(){read(n), read(m);for(int i = 1; i <= n; i++)read(a[i]), lst[i] = a[i];sort(lst + 1, lst + n + 1);tot = unique(lst + 1, lst + n + 1) - lst - 1;for(int i = 1; i <= n; i++)a[i] = lower_bound(lst + 1, lst + tot + 1, a[i]) - lst;for(int i = 1, u, v; i < n; i++)read(u), read(v), add(u, v), add(v, u);dfs(1, 0);init();build_tree();while(m--){int u, v, x;read(u), read(v), read(x);u ^= ans;ans = query(u, v, x);write(ans);if(m) enter;}return 0;
}

转载于:https://www.cnblogs.com/RabbitHu/p/BZOJ2588.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

会计未来十年发展趋势_谈未来十年会计行业的发展趋势

谈未来十年会计行业的发展方向&#xff0c;会计行业未来十年将变成什么样子?信息化和数据化改变着各行各业&#xff0c;会计行业也不例外&#xff0c;近十年会计行业发生了翻天覆地的变化&#xff0c;10年后&#xff0c;我想还会有巨大的变化。具体变化预想如下&#xff1a;1.…

QT使用Q_OBJECT链接不通过的一种情况

今天在main里自定义继承于QObject的类&#xff0c;添加了Q_OBJECT宏和信号之后&#xff0c;总是链接不通过&#xff0c;提示XXXX::staticMetaObject等等不存在。 后来得知在cpp里定义的Q_OBJECT,需要添加额外步骤才能编译通过。 下面是找到的一段文档&#xff0c;原文&#xff…

实验5: IOS的升级与恢复

实验5: IOS的升级与恢复 实验目的通过本实验可以掌握 1) 掌握IOS 正常的情况下升级IOS2) IOS 丢失的情况下使用TFTP恢复IOS3) IOS 丢失的情况下使用Xmodem恢复IOS 拓扑结构 实验步骤n IOS 正常的情况下升级IOS (TFTP)Router#conf t //进…

element的分页怎么改中文配置_vue想改变element分页样式

我想要把左边靠左 右边pager靠右.el-pagination .btn-next {background: center center no-repeat #fff;background-size: 16px;cursor: pointer;color: #103133;float:right;}.el-pagination .btn-prev {background: center center no-repeat #fff;background-size: 16px;curs…

MYSQL:基础——触发器

MYSQL基础——触发器 引入触发器 什么是触发器 如果你想要某条语句(或某些语句)在事件发生时自动执行。比如&#xff1a; 每当订购一个产品时&#xff0c;都从库存数量中减去订购的数量&#xff1b;无论何时删除一行&#xff0c;都在某个存档表中保留一个副本。就需要用到触发器…

双线macd指标参数最佳设置_常用指标知多少(二)

均线日期的选择种类有很多&#xff0c;一般行情软件常用的均线日期是5日、10日、20日、30日和60日&#xff0c;一般也会默认是这些日期&#xff0c;也有的加上了长线的120日和250日&#xff0c;很好理解&#xff0c;因为每周交易日是5天&#xff0c;所以以倍数做比较。使用海龟…

VI高级命令集锦

1.交换两个字符位置xp2.上下两行调换ddp3.把文件内容反转:g/^/m0/ (未通过)4.上下两行合并 J5.删除所有行 dG6.从当前位置删除到行尾d$7.从当前位置复制到行尾y$ 如果要粘贴到其他地方 p 就可以了由于vi 是建立在 EX 上的 所以 当键入 : 时就来到了 EX 命令状态 8.:ab string s…

图片合成gif_使用在线图片工具处理静态和动态图片的技巧

图片一般分为两种&#xff0c;一种是静态图片&#xff0c;常用的图片格式有jpg&#xff0c;png等。处理静态图片可用用手机自己带的图片处理工具处理&#xff0c;也能够使用线上的在线作图工具来进行操作&#xff0c;比如找图设计&#xff0c;懒设计&#xff0c;稿定设计等设计…

Redis源代码分析之sds, 动态数组

Redis是用C语言编写的。C语言处理字符串一向是个难点。很容易出现内存越界问题。 其它高级语言很容易实现的字符串拼接&#xff0c;在C这里却是百般艰难。因为需要实现计算出字符串所占内存的大小。即不能过大&#xff08;浪费内存&#xff09;&#xff0c;也不能太小&#xff…

kaldi windows安装_kaldi在Windows下的使用

其实不是特别推荐在Windows下使用kaldi&#xff0c;因为在egs下所有的脚本都无法运行&#xff0c;我也是弄了很久才在Windows下配置好kaldi&#xff0c;都一度差点弃坑。就连官方也说There is no commitment to support Windows. The Windows port of Kaldi is targeted at exp…

C#委托的异步调用[转]

本文将主要通过“同步调用”、“异步调用”、“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊。 首先&#xff0c;通过代码定义一个委托和下面三个示例将要调用的方法&#xff1a; /*添加的命名空间using System.Threading;using System.Runtime.…

[Python] isinstance() for checking object type

isinstance("foo", str) isinstance(1, int) isinstance(4.0, float) 转载于:https://www.cnblogs.com/Answer1215/p/8018722.html

钉钉微应用怎么进入_蓝凌携手钉钉走进越秀地产,零距离热聊企业数字化转型...

8月18日&#xff0c;蓝凌携手钉钉一同走进越秀地产&#xff0c;举办了《地产行业数字化实战闭门分享会》主题活动&#xff0c;与30余名嘉宾欢聚一堂&#xff0c;体验智慧管理实践与数字工作模式&#xff0c;探索企业数字化转型升级之道。越秀地产CIO陈磊、越秀地产信息总监郑毅…

mysql5.7半自动同步设置【转】

mysql的主从复制主要有3种模式&#xff1a; a..主从同步复制&#xff1a;数据完整性好&#xff0c;但是性能消耗高 b.主从异步复制&#xff1a;性能消耗低&#xff0c;但是容易出现主从数据唯一性问题 c.主从半自动复制&#xff1a;介于上面两种之间。既能很好的保持完整性&…

virsh 关机_kvm虚拟机不能使用virsh shutdownw命令关闭虚拟机的解决方法

今天笔者在对kvm虚拟机进行管理时&#xff0c;使用virsh shutdown命令关闭指定的虚拟机时&#xff0c;发现虽然有如下的提示&#xff0c;但其实虚拟机却一直不会真正的关闭。经过查看virsh命令帮助和上网查询&#xff0c;才得知virsh shutdown命令使用发送acpi指令来控制虚拟机…

Android之旅---广播(BroadCast)

什么是广播在Android中&#xff0c;Broadcast是一种广泛运用的在应用程序之间传输信息的机制。我们拿广播电台来做个比方。我们平常使用收音机收音是这样的&#xff1a;许许多多不同的广播电台通过特定的频率来发送他们的内容&#xff0c;而我们用户只需要将频率调成和广播电台…

python牛客网编程题_【面经】小米软件开发一面(python)面经 2020 2020

作者&#xff1a;JessyTsuihttps://www.nowcoder.com/discuss/580721?type2&order0&pos15&page1&channel-1&source_iddiscuss_tag_nctrack来源&#xff1a;牛客网小米软件开发一面(python)面经一共三轮技术面&#xff0c;第四轮是HR面&#xff0c;已OC&am…

IDS与IPS

IDS是英文“Intrusion Detection Systems”的缩写&#xff0c;中文意思是“***检测系统”。专业上讲就是依照一定的安全策略&#xff0c;对网络、系统的运行状况进行监视&#xff0c;尽可能发现各种***企图、***行为或者***结果&#xff0c;以保证网络系统资源的机密性、完整性…

c# 数组和集合

数组是最为常见的一种结构&#xff0c;是相同类型的、用一个标识符封装到一起的j基本类型数据序列或对象序列&#xff0c;可以用一个统一的数组名和下标来唯一确定数组中的元素。实质上数组是一个简单的线性序列&#xff0c;因此数组访问起来很快。而集合可以看成一种特殊的数组…

和vs版本关系_栈局部变量优化探究,意外发现了 vs 的一个 bug ?

缘起 我在《栈又溢出了》一文中记录了一个奇怪的栈溢出问题。虽然解决了&#xff0c;但是总感觉哪里不太合理。我想&#xff0c;vs 一定有一个合理的设置。一起折腾起来吧&#xff01;查找工程设置 本以为能找到某个编译选项对局部变量占用内存的行为进行控制。看遍了工程设置也…