树链剖分换根模板
具体思想:
换根后,一条链上的信息不回被改变。 在下图中2-1-3-7-8这条链不管是哪一个点事根节点,就可以是2-1-3-7-8
但是子树的信息会被改变。
以下图为例,
假设有一颗树,最初始的根为1
现在进行一次换根操作,将1换为 r o o t root root,查询以3为根的子树的权值和。
有以下三种情况:
当 r o o t = 3 root=3 root=3时: a n s = ans= ans=所有点的权值
当 r o o t root root不在原图中以3为根的子树时(即 r o o t ≠ 3 , 6 , 7 , 8 root\not= 3,6,7,8 root=3,6,7,8)不妨设 r o o t = 2 root=2 root=2。可以看出,以3为根的子树所有信息并不会改变
当 r o o t root root在原图中以3为根的子树时(即 r o o t = 3 o r 6 o r 7 o r 8 root= 3or6or7or8 root=3or6or7or8)不妨设 r o o t = 8 root=8 root=8。此时, a n s ans ans=全部点的权值减去7,8的权值。对应原图,找到要查询的点到 r o o t root root路径上的第一个儿子。这个儿子对应的原树中的子树+要查询的点所在子树=全集。
所以我们换根操作就变成将所有点的权值和减去要查询的点到 r o o t root root路径上的第一个儿子对应的原树中的子树的权值和
修改操作也类似
code:
#include <bits/stdc++.h>
#define ll long long
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int maxn=100005;
template<typename t>void read(t &x)
{
x=0;int f=1;char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch==