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 这也是个模 ...
随机推荐
- cmake编译后vs编译(build Solution)报错的解决办法
很久没有写blog了,最近在kdevelop上开发程序的时候,需要在主函数的文件中引用别的文件的函数,添加了对该函数所在的头文件之后仍然出现该函数没有定义的错误.经历了一番波折之后,才发现是忘记了在c ...
- 我的.emacs文件,用于C/C++及shell编程。
1. [代码]我的.emacs文件,用于C/C++及shell编程.;;我的配置;;1.基本配置;;外观配置***************;;禁用启动画面(setq inhibit-startup-m ...
- MyBatis映射文件中用#和$传递参数的特点
在MyBatis映射文件中用#和$传递参数的特点, #是以占位符的形式来传递对应变量的参数值的,框架会对传入的参数做预编译的动作, 用$时会将传入的变量的参数值原样的传递过去,并且用$传递传递参数的时 ...
- leetcode 111 Minimum Depth of Binary Tree(DFS)
Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...
- 每天一个Linux命令(2):ls命令
版权声明 更新:2017-04-26博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下命令ls. 2 开 ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)
2017-03-16 11:23:29.601 1238 ERROR nova.compute.manager [instance: 3f195047-250a-4eb5-8da0-63bea6e26 ...
- 《精通Spring4.X企业应用开发实战》读后感第四章(BeanFactory生命周期)
package com.smart; import org.springframework.beans.BeansException; import org.springframework.beans ...
- day12Session案例 JSP
2 Session案例 用户登录场景 package gz.itcast; import java.io.IOException; import java.io.PrintWriter; import ...
- C++开源库(一) ----libConfig详解
博主天生患有蛋疼疾病,写博不易,转载注明出处http://www.cnblogs.com/liboBlog/,谢谢! 在写程序的时候必不可少的一个部分就是conf文件的解析,但是如果自己解析的话会比较 ...
- java反射机制基础总结
1反射机制是啥? 反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变.通俗的讲就是反射可以在运行时根据指定的类名获得类的信息. 2反射机制有啥用? Reflection(反射) ...