洛谷p3384 【模板】树链剖分错误记录

首先感谢\(lfd\)在课上调了出来\(Orz\)

\(1\).以后少写全局变量

\(2\).线段树递归的时候最好把左右区间一起传

\(3\).写\(dfs\)的时候不要写错名字

\(4\).使用线段树的操作的时候才要用到\(dfs\)序

\(5\).需要开一个数组来记录在\(dfs\)序下的节点是什么也方便线段树的赋值

\(6\).注意\(down\)函数内怎样更新

\(7\).在查询的时候并不需要向上更新

由于\(yxj\)看了\(lfd\)敲的树链剖分感觉压完行之后非常的好看,由此\(yxj\)也踏上了疯狂压行的不归路

Code:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #define lson k << 1
  6. #define rson k << 1 | 1
  7. using namespace std;
  8. const int N = 1e5+7;
  9. int n, m, R, p, dfn[N], top[N], son[N], dep[N], fa[N], siz[N], tot, head[N << 1], cnt, num, x, y, z, w[N], l, r, ans, pre[N];
  10. struct node {int l, r, f, w;}tr[N << 2];
  11. struct Node {int nxt, to;}e[N << 1];
  12. int read() {
  13. int s = 0, w = 1;
  14. char ch = getchar();
  15. while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();}
  16. while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();}
  17. return s * w;
  18. }
  19. void build(int k, int l, int r) {
  20. tr[k].l = l, tr[k].r = r;
  21. if(l == r) {tr[k].w = w[pre[l]]; return;}
  22. int mid = (l + r) >> 1;
  23. build(lson, l, mid);
  24. build(rson, mid + 1, r);
  25. tr[k].w = (tr[lson].w + tr[rson].w) % p;
  26. }
  27. void add(int x, int y) {
  28. e[++cnt].nxt = head[x];
  29. e[cnt].to = y;
  30. head[x] = cnt;
  31. }
  32. void dfs(int x) {
  33. siz[x] = 1;
  34. dep[x] = dep[fa[x]] + 1;
  35. for(int i = head[x]; i; i = e[i].nxt) {
  36. if(e[i].to == fa[x]) continue;
  37. fa[e[i].to] = x, dfs(e[i].to), siz[x] += siz[e[i].to];
  38. if(siz[e[i].to] > siz[son[x]]) son[x] = e[i].to;
  39. }
  40. }
  41. void dfs1(int x) {
  42. dfn[x] = ++tot; pre[tot] = x;
  43. if(!top[x]) top[x] = x;
  44. if(son[x]) top[son[x]] = top[x], dfs1(son[x]);
  45. for(int i = head[x]; i; i = e[i].nxt)
  46. if(e[i].to != fa[x] && e[i].to != son[x]) dfs1(e[i].to);
  47. }
  48. void down(int k) {
  49. tr[lson].f += tr[k].f; tr[rson].f += tr[k].f;
  50. tr[lson].w += (tr[lson].r - tr[lson].l + 1) * tr[k].f;
  51. tr[rson].w += (tr[rson].r - tr[rson].l + 1) * tr[k].f;
  52. tr[k].f = 0;
  53. }
  54. void change_query(int k) {
  55. if(tr[k].l >= l && tr[k].r <= r) {tr[k].w += (tr[k].r - tr[k].l + 1) * z;tr[k].f += z; return;}
  56. if(tr[k].f) down(k);
  57. int mid = (tr[k].l + tr[k].r) >> 1;
  58. if(l <= mid) change_query(lson);
  59. if(r > mid) change_query(rson);
  60. tr[k].w = (tr[lson].w + tr[rson].w) % p;
  61. }
  62. void work(int x, int y) {
  63. z %= p;
  64. while(top[x] != top[y]) {
  65. if(dep[top[x]] < dep[top[y]]) swap(x, y);
  66. l = dfn[top[x]], r = dfn[x], change_query(1);
  67. x = fa[top[x]];
  68. }
  69. if(dep[x] > dep[y]) swap(x, y);
  70. l = dfn[x], r = dfn[y]; change_query(1);
  71. }
  72. void ask_query(int k) {
  73. if(tr[k].l >= l && tr[k].r <= r) {ans = (ans + tr[k].w) % p; return;}
  74. if(tr[k].f) down(k);
  75. int mid = (tr[k].l + tr[k].r) >> 1;
  76. if(l <= mid) ask_query(lson);
  77. if(r > mid) ask_query(rson);
  78. tr[k].w = (tr[lson].w + tr[rson].w) % p;
  79. }
  80. void work1(int x, int y) {
  81. while(top[x] != top[y]) {
  82. if(dep[top[x]] < dep[top[y]]) swap(x, y);
  83. l = dfn[top[x]], r = dfn[x]; ask_query(1);
  84. x = fa[top[x]];
  85. }
  86. if(dep[x] > dep[y]) swap(x, y);
  87. l = dfn[x]; r = dfn[y]; ask_query(1);
  88. }
  89. int main() {
  90. n = read(), m = read(), R = read(), p = read();
  91. for(int i = 1; i <= n; i++) w[i] = read();
  92. for(int i = 1; i < n; i++) x = read(), y = read(), add(x, y), add(y, x);
  93. dfs(R); dfs1(R); build(1, 1, n);
  94. while(m--) {
  95. num = read();
  96. if(num == 1) cin >> x >> y >> z, work(x, y);
  97. if(num == 2) ans = 0, cin >> x >> y, work1(x, y), cout << ans << endl;
  98. if(num == 3) cin >> x >> z, l = dfn[x], r = dfn[x] + siz[x] - 1, change_query(1);
  99. if(num == 4) ans = 0, cin >> x, l = dfn[x], r = dfn[x] + siz[x] - 1, ask_query(1), cout << ans << endl;
  100. }
  101. return 0;
  102. }

谢谢收看,祝身体健康!

洛谷p3384【模板】树链剖分题解的更多相关文章

  1. [洛谷P3384] [模板] 树链剖分

    题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...

  2. [luogu P3384] [模板]树链剖分

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

  3. 洛谷P3979 遥远的国度 树链剖分+分类讨论

    题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...

  4. 洛谷 P4114 Qtree1 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...

  5. 洛谷.4114.Qtree1(树链剖分)

    题目链接 模板题都错了这么多次.. //边权赋到点上 树剖模板 //注意LCA.链的顶端不能统计到答案! #include <cstdio> #include <cctype> ...

  6. 洛谷3384&bzoj1036树链剖分

    值得注意的是: 一个点的子树是存在一起的...也就是说我们修改子树的时候只用... /********************************************************* ...

  7. P3384 [模板] 树链剖分

    #include <bits/stdc++.h> using namespace std; typedef long long ll; int n, m, rt, mod, cnt, to ...

  8. luoguP3384 [模板]树链剖分

    luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...

  9. 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...

随机推荐

  1. 在 React 组件中监听 android 手机物理返回/回退/back键事件

    当前端页面嵌入到 webview 中运行时,有时会需要监听手机的物理返回按键事件来做一些自定义的操作. 比如我最近遇到的,在一个页面里面有批量选择的功能,当点击手机的返回键时,清除页面上的选中状态.我 ...

  2. pytorch——auto-encoders

    自动编码器的训练方法: (1)Loss function for binary inputs (2)Loss function for real-valued inputs

  3. 【mysql】修改mysql数据库密码

    修改mysql数据库密码 操作系统:Linux centos7 数据库:mysql5.7 一.在已知MYSQL数据库的ROOT用户密码的情况下,修改密码 1.在Linux命令行,使用mysqladmi ...

  4. Ubuntu 16.04上anaconda安装和使用教程,安装jupyter扩展等 | anaconda tutorial on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/23014ca5/,欢迎阅读最新内容! anaconda tutorial on ubuntu 16.04 Guide versio ...

  5. 在 Javascript 中,为什么给 form 添加了 onsubmit 事件,为什么 IE7/8 还是会提交表单?

    参考地址:http://stackoverflow.com/questions/4078245/onsubmit-return-false-has-no-effect-on-internet-expl ...

  6. Nginx自建SSL证书部署HTTPS网站

    一.创建SSL相关证书 1.安装Nginx(这里为了测试使用yum安装,实际看具体情况) [root@localhost ~]# yum install nginx -y #默认yum安装已经支持SS ...

  7. F#周报2019年第19期

    新闻 介绍.NET 5 发布.NET Core 3.0预览版5以及F#的REPL OpenFsharp CFP开启 F#的Giraffe服务端stub生成器被添加到openapi-generator中 ...

  8. 何谓SQLSERVER参数嗅探(转载)

    大家听到“嗅探”这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o .事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上跟数据库性能调优有关相 ...

  9. SSO单点登录和CAS

    一.单点登录流程 =====客户端====== 1.拦截客户端的请求判断是否有局部的session 2.1如果有局部的session,放行请求. 2.2如果没有局部session 2.2.1请求中有携 ...

  10. 手写instanceof (详解原型链) 和 实现绑定解绑和派发的事件类

    A  instanceof  B    是判断  A  是否继承自B,是返回true,  否返回false 再精确点就是判断B   是否  再  A  的 原型链上, 什么是原型链,举个例子: 我们定 ...