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 这也是个模 ...
随机推荐
- React之组件小析
组件就是标签,html的标签某种角度讲就是组件. index.js是项目的入口文件. react中大写字母开头的都是组件. App.js就是一个组件. ReactDOM会将组件内容,渲染到页面当中. ...
- 分享知识-快乐自己:Struts2 - result标签的name属性和type属性
1):result的name属性 例如:<result name="success">/pages/success.jsp</result> Strut ...
- 分享知识-快乐自己:Struts2(动态方法、动态结果、通配符、方法内部跳转、action跳转、OGNL 的使用及注意事项)
这里主要以案例演示:涵盖以下知识点 1.动态方法调用:使用关键 符号 ! 进行操作 例如:/命名空间 ! 方法名 2.动态结果集:就是说,通过后台返回的结果 ${} 获取,重定向到符合预期的页面. ...
- C#高性能Socket服务器SocketAsyncEventArgs的实现(IOCP)
网址:http://blog.csdn.net/zhujunxxxxx/article/details/43573879 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Socket ...
- listen and translation exercise 52
Two years ago my husband bought me a bicycle. Twenty of the thirty-five years I ran my own business. ...
- hdu-2586 How far away ?(lca+bfs+dfs+线段树)
题目链接: How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- bootstrap框架日期时间之年月选择及汉化
==>上次介绍了bootstrap框架日期时间 开始日期和结束日期选择 http://www.cnblogs.com/wjqblogs/p/4043198.html 今天又做了个只选择年月的日期 ...
- 取分组TOPN好理解案例
- P2024 [NOI2001]食物链[扩展域并查集]
大水题一道啊,几分钟切掉. 还是扩展域,每个点拆3个点,之间连边表示有关系(即捕食关系).然后随便判定一下就好了,不难,毕竟NOI上古题目. #include<iostream> #inc ...
- 【LeetCode】282. Expression Add Operators
题目: Given a string that contains only digits 0-9 and a target value, return all possibilities to add ...