原题链接

对于以u为根的子树,后代节点的dfn显然比他的dfn大,我们可以记录一下回溯到u的dfn,显然这两个dfn构成了一个连续区间,代表u及u的子树

剩下的就和树剖一样了

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #define N 100010
  5. typedef long long ll;
  6. using namespace std;
  7. int ecnt,head[N],son[N],fa[N],sz[N],n,m,r,deep[N],pos[N],indx[N],tot,op,back[N],top[N];
  8. ll val[N],P;
  9. struct adj
  10. {
  11. int nxt,v;
  12. }e[*N];
  13. struct node
  14. {
  15. int l,r;
  16. ll sum,lz;
  17. }t[*N];
  18. void add(int u,int v)
  19. {
  20. e[++ecnt].v=v;
  21. e[ecnt].nxt=head[u];
  22. head[u]=ecnt;
  23. e[++ecnt].v=u;
  24. e[ecnt].nxt=head[v];
  25. head[v]=ecnt;
  26. }
  27. void dfs1(int x,int father,int dep)
  28. {
  29. deep[x]=dep,fa[x]=father,sz[x]=;
  30. for (int i=head[x];i;i=e[i].nxt)
  31. {
  32. int v=e[i].v;
  33. if (fa[x]==v) continue;
  34. dfs1(v,x,dep+);
  35. sz[x]+=sz[v];
  36. if (sz[v]>sz[son[x]]) son[x]=v;
  37. }
  38. }
  39. void dfs2(int x,int TOP)
  40. {
  41. top[x]=TOP;
  42. pos[x]=++tot;
  43. indx[tot]=x;
  44. if (son[x]) dfs2(son[x],TOP);
  45. for (int i=head[x];i;i=e[i].nxt)
  46. {
  47. int v=e[i].v;
  48. if (v==fa[x] || v==son[x]) continue;
  49. dfs2(v,v);
  50. }
  51. back[x]=tot;
  52. }
  53. void pushdown(int p)
  54. {
  55. if (t[p].l==t[p].r || !t[p].lz) return;
  56. int w=t[p].lz;
  57. t[p<<].sum=(t[p<<].sum+w*(t[p<<].r-t[p].l+)%P)%P;
  58. t[p<<|].sum=(t[p<<|].sum+w*(t[p<<|].r-t[p<<|].l+)%P)%P;
  59. t[p<<].lz+=w;
  60. t[p<<].lz%=P;
  61. t[p<<|].lz+=w;
  62. t[p<<|].lz%=P;
  63. t[p].lz=;
  64. }
  65. void pushup(int p)
  66. {
  67. t[p].sum=(t[p<<].sum+t[p<<|].sum)%P;
  68. }
  69. void build(int p,int l,int r)
  70. {
  71. t[p].l=l,t[p].r=r,t[p].lz=;
  72. if (l!=r)
  73. {
  74. int mid=l+r>>;
  75. build(p<<,l,mid);
  76. build(p<<|,mid+,r);
  77. pushup(p);
  78. }
  79. else
  80. t[p].sum=val[indx[l]]%P;
  81. }
  82. void modify(int p,int l,int r,int w)
  83. {
  84. if (t[p].l==l && t[p].r==r)
  85. {
  86. t[p].sum+=w*(t[p].r-t[p].l+);
  87. t[p].lz+=w;
  88. return ;
  89. }
  90. pushdown(p);
  91. int mid=t[p].l+t[p].r>>;
  92. if (r<=mid) modify(p<<,l,r,w);
  93. else if (l>mid) modify(p<<|,l,r,w);
  94. else modify(p<<,l,mid,w),modify(p<<|,mid+,r,w);
  95. pushup(p);
  96. }
  97. ll query(int p,int l,int r)
  98. {
  99. if (t[p].l==l && t[p].r==r)
  100. return t[p].sum%P;
  101. int mid=t[p].l+t[p].r>>;
  102. pushdown(p);
  103. if (r<=mid) return query(p<<,l,r)%P;
  104. if (l>mid) return query(p<<|,l,r)%P;
  105. return (query(p<<,l,mid)+query(p<<|,mid+,r))%P;
  106. }
  107. void pathInc(int u,int v,int w)
  108. {
  109. while (top[u]!=top[v])
  110. {
  111. if (deep[top[u]]<deep[top[v]]) swap(u,v);
  112. modify(,pos[top[u]],pos[u],w);
  113. u=fa[top[u]];
  114. }
  115. if (deep[u]>deep[v]) swap(u,v);
  116. modify(,pos[u],pos[v],w);
  117. }
  118. ll pathQuery(int u,int v)
  119. {
  120. ll ret=;
  121. while (top[u]!=top[v])
  122. {
  123. if (deep[top[u]]<deep[top[v]]) swap(u,v);
  124. ret=(ret+query(,pos[top[u]],pos[u]))%P;
  125. u=fa[top[u]];
  126. }
  127. if (deep[u]>deep[v]) swap(u,v);
  128. return (ret+query(,pos[u],pos[v]))%P;
  129. }
  130. int main()
  131. {
  132. scanf("%d%d%d%lld",&n,&m,&r,&P);
  133. for (int i=;i<=n;i++)
  134. scanf("%lld",&val[i]);
  135. for (int i=,u,v;i<n;i++)
  136. scanf("%d%d",&u,&v),add(u,v);
  137. dfs1(r,,);
  138. dfs2(r,r);
  139. build(,,n);
  140. for (int i=,x,y,z;i<=m;i++)
  141. {
  142. scanf("%d",&op);
  143. if (op==)
  144. scanf("%d%d%d",&x,&y,&z),pathInc(x,y,z);
  145. else if (op==)
  146. scanf("%d%d",&x,&y),printf("%lld\n",pathQuery(x,y));
  147. else if (op==)
  148. scanf("%d%d",&x,&z),modify(,pos[x],back[x],z);
  149. else scanf("%d",&x),printf("%lld\n",query(,pos[x],back[x]));
  150. }
  151. return ;
  152. }

洛谷树剖模板题 P3384 | 树链剖分的更多相关文章

  1. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  2. 洛谷P3372 【模板】线段树 1

    P3372 [模板]线段树 1 153通过 525提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 [模板]线段树1(AAAAAAAAA- [模板]线段树1 洛谷 ...

  3. 洛谷P3373 【模板】线段树 2

     P3373 [模板]线段树 2 47通过 186提交 题目提供者HansBug 标签 难度提高+/省选- 提交  讨论  题解 最新讨论 为啥WA(TAT) 题目描述 如题,已知一个数列,你需要进行 ...

  4. 洛谷 P3373 【模板】线段树 2 解题报告

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上\(x\) 2.将某区间每一个数加上\(x\) 3.求出某区间每一个数的和 输入输出格式 ...

  5. 洛谷 P3372 【模板】线段树 1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  6. 洛谷—— P3372 【模板】线段树 1

    P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别 ...

  7. 洛谷——P3373 【模板】线段树 2&& B 数据结构

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 线段树维护区间乘法 1.如何 ...

  8. 洛谷 P3373 【模板】线段树 2 题解

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式 第一行包含三个整数 ...

  9. 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解

    题目传送: P3373 [模板]线段树 2  P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...

随机推荐

  1. 爬虫学习(十八)——selenium解决javascript渲染

    selenium 是一个用于Web应用程序测试的工具. Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fir ...

  2. SqlServer2008/2005数据库日志收缩

    1.SQL2008数据库USE [master]GOALTER DATABASE 数据库名称 SET RECOVERY SIMPLE WITH NO_WAITALTER DATABASE 数据库名称 ...

  3. HAN模型理解2

    Hierarchical Attention Networks for Document Classification 论文的理解 在论文的摘要中,它提出了论文的两个特点.第一个就是对应文章所有具有的 ...

  4. POJ-2251 三维迷宫

    题目大意:给一个三维图,可以前后左右上下6种走法,走一步1分钟,求最少时间(其实就是最短路) 分析:这里与二维迷宫是一样的,只是多了2个方向可走,BFS就行(注意到DFS的话复杂度为O(6^n)肯定会 ...

  5. rpm、yum命令

    一.rpm命令 挂载光盘文件到/media目录: 进去/media目录下的Packages目录: 查看系统已安装的所有rpm包: 查看系统是否安装dhcp软件包: 安装dhcp软件包: 查看dhcp软 ...

  6. talent-aio源码阅读小记(二)

    我们上一篇提到了talent-aio的四类Task:DecodeRunnable.HandlerRunnable.SendRunnable.CloseRunnable,并且分析了这些task的基类Ab ...

  7. 3 web框架

    web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法. ...

  8. 14,flask-sqlalchemy项目配置

    基于一个flask项目,加入flask-SQLAlchemy 1.加入falsk-sqlalchemy第三方组件 from flask import Flask # 导入Flask-SQLAlchem ...

  9. CSS继承特殊

    继承 CSS的某些样式具有继承性.继承是一种规则,它允许样式不仅作用于某个特定html标签元素,而且应用于其后代   如:在p中的所有字体都为红色     p{color:red;}    <p ...

  10. 变量存储类型(auto static extern)

    auto 动态存储类型变量(函数内部变量存储默认为 auto型) auto只用于函数内部定义,单片机在执行这个函数时为它分配内存地址,当函数执行完毕返回后,auto变量会被销毁,再次进入这个函数时,它 ...