原题链接

对于以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[2*N];
 13 struct node
 14 {
 15     int l,r;
 16     ll sum,lz;
 17 }t[4*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]=1;
 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+1);
 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<<1].sum=(t[p<<1].sum+w*(t[p<<1].r-t[p].l+1)%P)%P;
 58     t[p<<1|1].sum=(t[p<<1|1].sum+w*(t[p<<1|1].r-t[p<<1|1].l+1)%P)%P;
 59     t[p<<1].lz+=w;
 60     t[p<<1].lz%=P;
 61     t[p<<1|1].lz+=w;
 62     t[p<<1|1].lz%=P;
 63     t[p].lz=0;
 64 }
 65 void pushup(int p)
 66 {
 67     t[p].sum=(t[p<<1].sum+t[p<<1|1].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=0;
 72     if (l!=r)
 73     {
 74     int mid=l+r>>1;
 75     build(p<<1,l,mid);
 76     build(p<<1|1,mid+1,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     { 87     t[p].sum+=w*(t[p].r-t[p].l+1);
 88     t[p].lz+=w;
 89     return ;
 90     }
 91     pushdown(p);
 92     int mid=t[p].l+t[p].r>>1;
 93     if (r<=mid) modify(p<<1,l,r,w);
 94     else if (l>mid) modify(p<<1|1,l,r,w);
 95     else modify(p<<1,l,mid,w),modify(p<<1|1,mid+1,r,w);
 96     pushup(p);
 97 }
 98 ll query(int p,int l,int r)
 99 {
100     if (t[p].l==l && t[p].r==r)
101     return t[p].sum%P;
102     int mid=t[p].l+t[p].r>>1;
103     pushdown(p);
104     if (r<=mid) return query(p<<1,l,r)%P;
105     if (l>mid) return query(p<<1|1,l,r)%P;
106     return (query(p<<1,l,mid)+query(p<<1|1,mid+1,r))%P;
107 }
108 void pathInc(int u,int v,int w)
109 {
110     while (top[u]!=top[v])
111     {
112     if (deep[top[u]]<deep[top[v]]) swap(u,v);
113     modify(1,pos[top[u]],pos[u],w);
114     u=fa[top[u]];
115     }
116     if (deep[u]>deep[v]) swap(u,v);
117     modify(1,pos[u],pos[v],w);
118 }
119 ll pathQuery(int u,int v)
120 {
121     ll ret=0;
122     while (top[u]!=top[v])
123     {
124     if (deep[top[u]]<deep[top[v]]) swap(u,v);
125     ret=(ret+query(1,pos[top[u]],pos[u]))%P;
126     u=fa[top[u]];
127     }
128     if (deep[u]>deep[v]) swap(u,v);
129     return (ret+query(1,pos[u],pos[v]))%P;
130 }
131 int main()
132 {
133     scanf("%d%d%d%lld",&n,&m,&r,&P);
134     for (int i=1;i<=n;i++)
135     scanf("%lld",&val[i]);
136     for (int i=1,u,v;i<n;i++)
137     scanf("%d%d",&u,&v),add(u,v);
138     dfs1(r,0,0);
139     dfs2(r,r);
140     build(1,1,n);
141     for (int i=1,x,y,z;i<=m;i++)
142     {
143     scanf("%d",&op);
144     if (op==1)
145         scanf("%d%d%d",&x,&y,&z),pathInc(x,y,z);
146     else if (op==2)
147         scanf("%d%d",&x,&y),printf("%lld\n",pathQuery(x,y));
148     else if (op==3)
149         scanf("%d%d",&x,&z),modify(1,pos[x],back[x],z);
150     else scanf("%d",&x),printf("%lld\n",query(1,pos[x],back[x]));
151     }
152     return 0;
153 }

转载于:https://www.cnblogs.com/mrsheep/p/7892142.html

洛谷树剖模板题 P3384 | 树链剖分相关推荐

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

    洛谷 P3373 [模板]线段树 2 题解 题面 题目链接:[戳这里](https://www.luogu.org/problemnew/show/P3373) 题目描述 输入输出格式 输入输出样例 ...

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

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

  3. 洛谷 P3372 【模板】线段树 1(线段树区间加区间找)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...

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

    文章目录 题目描述 输入格式 输出格式 输入输出样例 说明 [样例解释] AC的C++代码(结合注释理解) 题目描述 如题,已知一个数列,你需要进行下面两种操作: 将某区间每一个数加上k. 求出某区间 ...

  5. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  6. 洛谷 P3373 【模板】线段树 2(线段树区间乘、加 区间查找)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式 第一行包含三个整数N.M.P,分别表示该数列数字的 ...

  7. 洛谷 3373 【模板】线段树 2

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

  8. 洛谷-3373 【模板】线段树 2

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别 ...

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

    https://www.luogu.org/problem/P3373 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每 ...

最新文章

  1. 分享几个用 Python 给图片添加水印的方法,简单实用
  2. 多级反馈队列列算法的优点
  3. How to solve random black screen on macOS Sierra
  4. ListView的Columns自适应内部文字
  5. [Winform]安装在C盘,无操作权限的一个解决办法
  6. mysql一对多代码_MySQL实现一对多查询的代码示例
  7. 分支-08. 高速公路超速处罚
  8. MOSS 2007基础:内容类型(Content Type)之二
  9. Subversion under Linux [Reprint]
  10. dataimagepng php_PHP decode data:image/png;base64
  11. 【机器学习】鸢尾花数据探索
  12. 设计模式--工厂模式(c++)
  13. Codeforces Round #FF(255) DIV2
  14. opengl 遇到的基础问题
  15. springboot项目去除druid监控的广告超链接等
  16. 桌面快捷方式图标不能删除的原因以及处理方法
  17. 中国车牌号的分类说明识别及含义
  18. linux系统update和upgrade区别
  19. 10张剪纸风格2021牛年祝福海报
  20. 关于博客的论文php,基于php的个人博客系统毕业设计论文

热门文章

  1. 重启php-fpm的方法
  2. Oracle lower() Upper()函数
  3. leetcode练习——数组篇(1)(std::ios::sync_with_stdio(false);std::cin.tie(nullptr);)
  4. OpenDDS通讯中rtps_discovery对等发现的基本配置和说明
  5. 《App后台开发运维与架构实践》第3章 App后台核心技术
  6. 小程序学习(一):点击爱心变色 -- 最简单的事件实现
  7. 雪碧图sprity 合并多图使用心得
  8. 疯狂java学习笔记1023---线程的同步
  9. 服务器内存延迟,内存带宽、延迟性能测试
  10. 北海市计算机等级考试,2021上半年北海市计算机二级报名时间|网上报名入口【已开通】...