Luogu P3384 【模板】树链剖分
。。。rt。。。安利一发大佬博客https://www.cnblogs.com/ivanovcraft/p/9019090.html
注意:不要把dfn和rw弄混了。。。
#include<cstdio>
#include<iostream>
#define ll long long
#define R register ll
#define ls (tr<<1)
#define rs (tr<<1|1)
const int M=;
using namespace std;
inline ll g() {
R ret=; register char ch; while(!isdigit(ch=getchar())) ;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret;
}
int n,m,tr,cnt,num,mod;
int vr[M<<],nxt[M<<],fir[M],dfn[M],pre[M],d[M],sz[M],son[M],top[M],rw[M],w[M];
int tg[M<<],sum[M<<];
inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
void dfs(int u) { sz[u]=; R mx=;
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(!d[v]) {
pre[v]=u; d[v]=d[u]+; dfs(v); sz[u]+=sz[v];
if(sz[v]>mx) son[u]=v,mx=sz[v];
}
}
}
void dfs_(int u,int tp) {
top[u]=tp,dfn[u]=++num,rw[num]=u;
if(son[u]) dfs_(son[u],tp);
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(v!=pre[u]&&v!=son[u]) dfs_(v,v);
}
}
inline void build(int tr,int l,int r) {
if(l==r) {sum[tr]=w[rw[l]]; if(sum[tr]>=mod) sum[tr]%=mod; return ;}
R md=(l+r)>>; build(ls,l,md),build(rs,md+,r);
sum[tr]=(sum[ls]+sum[rs])%mod;
}
inline void spread(int tr,int len) {
if(tg[tr])
(tg[ls]+=tg[tr])%=mod,(sum[ls]+=(len-(len>>))*tg[tr])%=mod,
(tg[rs]+=tg[tr])%=mod,(sum[rs]+=(len>>)*tg[tr])%=mod,tg[tr]=;
}
inline int query(int tr,int l,int r,int LL,int RR) { R ret=;
if(LL<=l&&r<=RR) {return sum[tr];} spread(tr,r-l+); R md=(l+r)>>;
if(LL<=md) (ret+=query(ls,l,md,LL,RR))%=mod;
if(RR>md) (ret+=query(rs,md+,r,LL,RR))%=mod; return ret;
}
inline void update(int tr,int l,int r,int LL,int RR,int inc) {
if(LL<=l&&r<=RR) {(tg[tr]+=inc)%=mod,(sum[tr]+=(r-l+)*inc)%=mod; return ;}
spread(tr,r-l+); R md=(l+r)>>;
if(LL<=md) update(ls,l,md,LL,RR,inc);
if(RR>md) update(rs,md+,r,LL,RR,inc);
sum[tr]=(sum[ls]+sum[rs])%mod;
}
inline void change(int u,int v,int inc) {
while(top[u]!=top[v]) {
if(d[top[u]]<d[top[v]]) swap(u,v);
update(,,n,dfn[top[u]],dfn[u],inc);
u=pre[top[u]];
} if(dfn[u]>dfn[v]) swap(u,v);
update(,,n,dfn[u],dfn[v],inc);
}
inline int qTree(int u,int v) {
R ret=;
while(top[u]!=top[v]) {
if(d[top[u]]<d[top[v]]) swap(u,v);
(ret+=query(,,n,dfn[top[u]],dfn[u]))%=mod;
u=pre[top[u]];
} if(dfn[u]>dfn[v]) swap(u,v); (ret+=query(,,n,dfn[u],dfn[v]))%=mod;
return ret;
}
signed main() {
n=g(),m=g(),tr=g(),mod=g();
for(R i=;i<=n;++i) w[i]=g();
for(R i=,u,v;i<n;++i) u=g(),v=g(),add(u,v),add(v,u); cnt=;
d[tr]=; dfs(tr),dfs_(tr,tr); build(,,n);
//for(R i=1;i<=n;++i) cout<<sz[i]<<d[i]<<dfn[i]<<pre[i]<<son[i]<<top[i]<<endl;
for(R i=;i<=m;++i) {
R k=g(),u=g(),v,inc; //cout<<k<<u<<endl;
if(k==) v=g(),inc=g(),change(u,v,inc%mod);
else if(k==) v=g(),printf("%lld\n",qTree(u,v));
else if(k==) v=g(),update(,,n,dfn[u],dfn[u]+sz[u]-,v%mod);
else printf("%lld\n",query(,,n,dfn[u],dfn[u]+sz[u]-));
}
}
2019.04.19
Luogu P3384 【模板】树链剖分的更多相关文章
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- 【Luogu P3384】树链剖分模板
树链剖分的基本思想是把一棵树剖分成若干条链,再利用线段树等数据结构维护相关数据,可以非常暴力优雅地解决很多问题. 树链剖分中的几个基本概念: 重儿子:对于当前节点的所有儿子中,子树大小最大的一个儿子就 ...
- [洛谷P3384] [模板] 树链剖分
题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...
- P3384 [模板] 树链剖分
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n, m, rt, mod, cnt, to ...
- luoguP3384 [模板]树链剖分
luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...
- 模板 树链剖分BFS版本
//点和线段树都从1开始 //边使用vector vector<int> G[maxn]; ],num[maxn],iii[maxn],b[maxn],a[maxn],top[maxn], ...
- 『题解』洛谷P3384 【模板】树链剖分
Problem Portal Portal1: Luogu Description 如题,已知一棵包含\(N\)个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作\(1\): ...
- 树链剖分详解(洛谷模板 P3384)
洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...
- [note]树链剖分
树链剖分https://www.luogu.org/problemnew/show/P3384 概念 树链剖分,是一种将树剖分成多条不相交的链的算法,并通过其他的数据结构来维护这些链上的信息. 最简单 ...
- Luogu P3384 【【模板】树链剖分】
转载请注明出处,部分内容引自banananana大神的博客 ~~别说你不知道什么是树~~╮(─▽─)╭(帮你百度一下) 先来回顾两个问题:1,将树从x到y结点最短路径上所有节点的值都加上z 这也是个模 ...
随机推荐
- jira与wiki官方文档记录
jira:https://confluence.atlassian.com/display/JIRA/Home wiki:https://confluence.atlassian.com/doc/co ...
- apace搭建站点
Listen 127.0.0.1:3310<VirtualHost *:3306> ServerName 127.0.0.1:3306 DocumentRoot "F:/Baid ...
- cifs挂载远程文件出现 No such device or address错误
1. 参考 https://www.raspberrypi.org/forums/viewtopic.php?t=82199 找了两天看到这个文章才解决了问题. 我是之前同事在windows上挂载成功 ...
- 连接并同步windows下的git仓库
1. 需求 电脑A和电脑B本来通过服务器同步工作目录.服务器时linux系统上有个裸仓库,不管在A上还是B上工作,工作完毕后使用git go与服务器仓库同步.A和B都是windows系统,在工作目录下 ...
- [原创]Java动态生成word文档(图文并茂)
很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...
- logback备注
<?xmlversion="1.0"encoding="UTF-8"?> <!-- <configuration>包含的属性 sc ...
- form 提交数据编码梳理
之前对form单提交的操作一直都是迷迷糊糊,知道怎么用,但是随着ajax2的出现,我们有更多的方式操作form表单提交,但是底层的原理我们要好好的做个梳理. 常见的form提交有post和get这两种 ...
- SpringBoot 版本升级后报错 Cannot instantiate interface org.springframework.context.ApplicationContextInitializer
本篇博客纯粹讲我遇到这个问题的解决以及思考,如果你想知道解决方法,可以直接看正确解决方案部分.因为是前端写的,所以可能有些明显的内容很容易就看出来了. 首先:升级后更新其他依赖,以及Applicati ...
- <十五>UML核心视图动态视图之活动图
一:动态视图 --->动态视图是描述事物动态行为的. --->需要注意的是:动态视图不能够独立存在,它必需特指一个静态视图活uml元素,说明在静态视图规定的事物结构下它们的动态行为. -- ...
- 【Lintcode】159.Find Minimum in Rotated Sorted Array
题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 ...