题意

题目链接

Sol

从上午九点淦到现在qwq

思路比较简单,就是把每次加入的一坨点看成一个,然后直接倍增搞。。

然后慢慢调就可以了。。。

最后数量级会到达\(10^{10}\),所以应该开long long

  1. #include<bits/stdc++.h>
  2. #define Pair pair<LL, LL>
  3. #define MP make_pair
  4. #define fi first
  5. #define se second
  6. #define LL long long
  7. #define int long long
  8. using namespace std;
  9. const int MAXN = 1e5 + 10, B = 17, SS = 7e6 + 10;
  10. inline LL read() {
  11. char c = getchar(); LL x = 0, f = 1;
  12. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  13. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  14. return x * f;
  15. }
  16. int N, M, Q;
  17. vector<int> v[MAXN];
  18. int siz[MAXN], top[MAXN], son[MAXN], fa[MAXN], ID[MAXN], rev[MAXN], tim;
  19. LL dep[MAXN];
  20. void dfs1(int x, int _fa) {
  21. siz[x] = 1; dep[x] = dep[_fa] + 1; fa[x] = _fa;
  22. ID[x] = ++tim; rev[tim] = x;
  23. for(auto &to : v[x]) {
  24. if(to == _fa) continue;
  25. dfs1(to, x);
  26. siz[x] += siz[to];
  27. if(siz[to] > siz[son[x]]) son[x] = to;
  28. }
  29. }
  30. void dfs2(int x, int topf) {
  31. top[x] = topf;
  32. if(!son[x]) return ;
  33. dfs2(son[x], topf);
  34. for(auto &to : v[x]) {
  35. if(top[to]) continue;
  36. dfs2(to, to);
  37. }
  38. }
  39. int LCA(int x, int y) {
  40. while(top[x] ^ top[y]) {
  41. if(dep[top[x]] < dep[top[y]]) swap(x, y);
  42. x = fa[top[x]];
  43. }
  44. if(dep[x] < dep[y]) swap(x, y);
  45. return y;
  46. }
  47. LL GetDis(int x, int y) {
  48. int lca = LCA(x, y);
  49. return dep[x] + dep[y] - 2 * dep[lca];
  50. }
  51. int tot;
  52. struct Ope {
  53. int l, r, id, fa, ti;//id所在的根节点是哪个,fa连到了大树哪个节点下面 ti第几次操作
  54. bool operator < (const Ope &rhs) const {
  55. return r < rhs.r;
  56. }
  57. }md[MAXN];
  58. set<Ope> lin;
  59. int root[SS], si[SS], ls[SS], rs[SS], cnt;
  60. void insert(int &k, int pre, int l, int r, int v) {
  61. k = ++cnt; ls[k] = ls[pre]; rs[k] = rs[pre]; si[k] = si[pre] + 1;
  62. if(l == r) return;
  63. int mid = (l + r) >> 1;
  64. if(v <= mid) insert(ls[k], ls[pre], l, mid, v);
  65. else insert(rs[k], rs[pre], mid + 1, r, v);
  66. }
  67. int Query(int tl, int tr, int l, int r, int k) {
  68. if(l == r) return l;
  69. int cur = si[ls[tr]] - si[ls[tl]], mid = (l + r) >> 1;
  70. if(cur >= k) return Query(ls[tl], ls[tr], l, mid, k);
  71. else return Query(rs[tl], rs[tr], mid + 1, r, k - cur);
  72. }
  73. int Kth(int x, int k) {//以x节点为根的子树中第k小的节点
  74. int l = ID[x], r = ID[x] + siz[x] - 1;
  75. int tmp = Query(root[l - 1], root[r], 1, N, k);
  76. //printf("%d %d %d\n", x, k, tmp);
  77. return tmp;
  78. }
  79. Pair GetId(int x) {//大树中编号为x节点对应的小树中的节点编号,以及该节点被加入的时间
  80. Ope nl = *lin.lower_bound((Ope){0, x, 0, 0, 0});
  81. return {Kth(nl.id, x - nl.l + 1), nl.ti};
  82. }
  83. vector<int> V[MAXN];
  84. int Fa[MAXN][B + 1];
  85. LL Dep[MAXN], Dis[MAXN][B + 1], t[MAXN][B + 1];
  86. void Dfs(int x, int fa) {
  87. Dep[x] = Dep[fa] + 1;
  88. for(auto &to : V[x]) {
  89. if(to == fa) continue;
  90. Dfs(to, x);
  91. }
  92. }
  93. void Pre() {
  94. for(int j = 1; j <= B; j++)
  95. for(int i = 1; i <= M; i++) {
  96. Fa[i][j] = Fa[Fa[i][j - 1]][j - 1];
  97. t[i][j] = t[Fa[i][j - 1]][j - 1];
  98. Dis[i][j] = Dis[i][j - 1] + Dis[Fa[i][j - 1]][j - 1];
  99. }
  100. }
  101. LL calc(int x) {//计算大树中编号为x的节点到所在大节点的根的距离
  102. Pair tmp = GetId(x);
  103. return dep[tmp.fi] - dep[md[tmp.se].id];
  104. }
  105. LL Query(LL x, LL y) {//大树中编号为x, y的节点的距离
  106. Pair bx = GetId(x), by = GetId(y);
  107. if(bx.se == by.se) return GetDis(bx.fi, by.fi);
  108. LL prex = x, prey = y, gx, gy;
  109. x = bx.se; y = by.se;
  110. if(Dep[x] < Dep[y]) swap(x, y), swap(prex, prey);
  111. LL ans = calc(prex);
  112. for(int i = B; ~i; i--)
  113. if(Dep[Fa[x][i]] >= Dep[y]) {
  114. if(Fa[x][i] == y) {
  115. gx = GetId(t[x][i]).fi;
  116. gy = GetId(prey).fi;
  117. return ans + Dis[x][i] + GetDis(gx, gy) - (dep[gx] - dep[md[Fa[x][i]].id]);
  118. }
  119. ans += Dis[x][i], x = Fa[x][i];
  120. }
  121. // if(x == y) return ans - 2 * calc(prey);
  122. for(int i = B; ~i; i--)
  123. if(Fa[x][i] != Fa[y][i]) {
  124. ans += Dis[x][i]; ans += Dis[y][i];
  125. x = Fa[x][i], y = Fa[y][i];
  126. }
  127. gx = GetId(md[x].fa).fi, gy = GetId(md[y].fa).fi;
  128. return ans + 2 + GetDis(gx, gy) + calc(prey);
  129. }
  130. signed main() {
  131. //freopen("tree13.in", "r", stdin);freopen("b.out", "w", stdout);
  132. N = read(); M = read() + 1; Q = read();
  133. for(int i = 1; i <= N - 1; i++) {
  134. int x = read(), y = read();
  135. v[x].push_back(y);
  136. v[y].push_back(x);
  137. }
  138. dfs1(1, 0);
  139. dfs2(1, 1);//树剖
  140. for(int i = 1; i <= N; i++) insert(root[i], root[i - 1], 1, N, rev[i]);
  141. md[1] = {1, siz[1], 1, 0, 1};
  142. lin.insert(md[1]);
  143. tot = siz[1] + 1;
  144. for(int i = 2; i <= M; i++) {
  145. int x = read(), to = read();
  146. md[i] = {tot, tot + siz[x] - 1, x, to, i};
  147. lin.insert(md[i]);
  148. tot += siz[x];
  149. }
  150. for(int i = 2; i <= M; i++) {
  151. Ope x = md[i];
  152. int u = x.ti, v = GetId(x.fa).se;//大树以操作次序来标号
  153. V[v].push_back(u);
  154. Dis[u][0] = dep[GetId(md[u].fa).fi] - dep[md[v].id] + 1;
  155. Fa[u][0] = v;
  156. t[u][0] = md[u].fa;
  157. }
  158. Dfs(1, 0);
  159. Pre();
  160. while(Q--) {
  161. LL x = read(), y = read();
  162. cout << Query(x, y) << '\n';
  163. }
  164. return 0;
  165. }

洛谷P3248 [HNOI2016]树(主席树 倍增 )的更多相关文章

  1. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

  2. 洛谷P3567 KUR-Couriers [POI2014] 主席树/莫队

    正解:主席树/莫队 解题报告: 传送门! 这题好像就是个主席树板子题的样子,,,? 毕竟,主席树的最基本的功能就是,维护一段区间内某个数字的个数 但是毕竟是刚get到主席树,然后之前做的一直是第k大, ...

  3. 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)

    题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半 题解: 最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下 然后 WA80 WA80 WA0 WA90 WA80 ?? ...

  4. 洛谷P3567 [POI2014]KUR-Couriers 主席树

    挺裸的,没啥可讲的. 不带修改的主席树裸题 Code: #include<cstdio> #include<algorithm> using namespace std; co ...

  5. 洛谷$P3302$ 森林 $[SDOI2013]$ 主席树

    正解:主席树 解题报告: 传送门! 口胡一时爽代码火葬场 这题想法不难,,,但显然的是代码应该还挺难打的 但反正我也不放代码,就写下题解趴$QwQ$ 第一问就是个$Count\ on\ a\ tree ...

  6. 洛谷P4602 [CTSC2018]混合果汁(主席树)

    题目描述 小 R 热衷于做黑暗料理,尤其是混合果汁. 商店里有 nn 种果汁,编号为 0,1,\cdots,n-10,1,⋯,n−1 . ii 号果汁的美味度是 d_idi​ ,每升价格为 p_ipi ...

  7. 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大

    我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...

  8. 洛谷4137 mex题解 主席树

    题目链接 虽然可以用离线算法水过去,但如果强制在线不就gg了. 所以要用在线算法. 首先,所有大于n的数其实可以忽略,因为mex的值不可能大于n 我们来设想一下,假设已经求出了从0到n中所有数在原序列 ...

  9. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

随机推荐

  1. python -猜字小游戏

    代码运行效果如下: 注意: 1.必须要在python3环境想使用 2.QQ:3084276329(一起交流学习) 3.还请大家评论 Guess the word game代码如下: #! /usr/b ...

  2. Javascript如何避免连续调用中取到不存在的属性而导致报TypeError错?

    背景: 在最近的 NODEJS 项目中,涉及到数据库的查询,回调函数里返回了查询结果,我这样做处理然后返回给前端: return results.collect_coupon[0].count 但是这 ...

  3. 微信小程序报Cannot read property 'setData' of undefined的错误

    最近在学习微信小程序的开发,让我吐槽的是,都9102年了,怎么还是有有时不能复制,有时不能打中文的bug呢,这个时候,你可以Ctrl+shift+w一下,如果还不行,那就得重启了.. 进入正题吧,刚在 ...

  4. centos7搭建mysql5.7主从同步

    主从基本概念 mysql主从同步定义 主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave).因为复制是 ...

  5. 5_Python OOP

    1. 实例属性和类属性        (1) 实例属性在构造函数__init__中定义,定义时以self作为前缀,只能通过实例名访问        (2) 类属性在类中方法之外单独定义,还可以在程序中 ...

  6. 开机自启动Nginx的脚本

    1.1 编写shell脚本 这里使用的是编写shell脚本的方式来处理 vi /etc/init.d/nginx  (输入下面的代码) #!/bin/bash # nginx Startup scri ...

  7. C++中:默认构造函数、析构函数、拷贝构造函数和赋值函数——转

    对于一个空类,编译器默认产生4个成员函数:默认构造函数.析构函数.拷贝构造函数和赋值函数.1.构造函数:构造函数是一种特殊的类成员,是当创建一个类的时候,它被调用来对类的数据成员进行初始化和分配内存. ...

  8. docker OCI runtime

    Open Container Initiative(OCI)目前有2个标准:runtime-spec以及image-spec.前者规定了如何运行解压过的filesystem bundle.OCI规定了 ...

  9. EventProcessor与WorkPool用法--可处理多消费者

    单一的生产者,消费者有多个,使用WorkerPool来管理多个消费者: RingBuffer在生产Sequencer中记录一个cursor,追踪生产者生产到的最新位置,通过WorkSequence和s ...

  10. CentOS 7.3.1611编译安装Nginx1.10.3+MySQL5.7.16+PHP7.1.2

    前传: 1.CentOS 7.3.1611系统安装配置图解教程 http://www.jb51.net/os/RedHat/597874.html 2.CentOS服务器初始化设置 http://ww ...