树链剖分
       如果给出一棵树并为每个节点标号1234...n;并定义区间[x,y]为树上节点x到节点y的最短路所经过的所有节点组成的集合,注意是闭区间,包括x,y两个节点      
       树链剖分能够解决树上区间的操作,是线段树功能的强化版,但他也依赖着线段树。
       树链剖分尝试着把树分割为多条链,并按照dfs序对链排序并交给线段树维护,如果这个想法成立,那么所有的树上区间操作都成了多段区间的线段树操作。
       现在的问题转移到如何分链,能够保证任何树上区间进行分解时分出的链都较少?否则上诉尝试没有任何意义,前人给出了分法。按轻重链分,
       这里有必要介绍几种名词
               重儿子:父亲节点的所有儿子中子树结点数目最多(size最大)的结点;
               轻儿子:父亲节点中除了重儿子以外的儿子;
               重边:父亲结点和重儿子连成的边;
               轻边:父亲节点和轻儿子连成的边;
               重链:由多条重边连接而成的路径;
               轻链:由多条轻边连接而成的路径;
       如此想必读者已经知道如何去分了,但为什么这样分保证任何树上区间进行分解时分出的链都较少
简单证明:
       假设根编号为root
       则区间[x,y]分出的链一定少于[root,x][root,y]这两个区间分出的链的和
       问题可以简化为对于区间[root,x]分出的链的数量的复杂度的证明,
       我们尝试从根往节点x走,一走就走一整条剖分链,如果没有到达x,一定会走上一个轻儿子,每当走上一个轻儿子,问题递归为以轻儿子为根走向节点x,
       可以证明这样的走法每走一步,当前子树的节点数目减半,这是轻儿子的性质。
       我们顶多走Olgn步,这意味着分出的链为Olgn个。子问题证毕。
over
如何分链呢?
       两次dfs
       第一次记录父亲,记录子孙数量,回溯重儿子,
       第二次根据重儿子优先dfs,标记每个节点所属重链的起点,标记dfs序,
       依据dfs序把树变成链并交给线段树处理
       查询的时候便只需要依据每个节点所属重链起点和dfs序进行线段树区间查询,修改也是一样,都交给线段树处理
struct dissection:segment_tree,graph
{
static const ll maxn=2.1e5;
ll treen;
ll dep[maxn],dad[maxn],son[maxn],siz[maxn],tid[maxn],chain[maxn];
//siz,dep,son,dad,
void dfs1(ll u=1,ll father=1,ll deep=1)
{
dep[u]=deep;
dad[u]=father;
siz[u]=1;
for(ll i=head[u]; ~i; i=g[i].nex)
{
ll v=g[i].v;
if(v!=father)
{
dfs1(v,u,deep+1);
siz[u]+=siz[v];
if (son[u]==-1||siz[v]>siz[son[u]])son[u]=v;
}
}
}
//chain,tid,rnk;
void dfs2(ll u=1,ll s=1)
{
chain[u]=s;
tid[u]=++treen;
rnk[treen]=u;
if(son[u]==-1)return;
dfs2(son[u],s);
for (ll i=head[u]; ~i; i=g[i].nex)
{
ll v=g[i].v;
if(v!=son[u]&&v!=dad[u])dfs2(v,v);
}
}
ll query_path(ll x,ll y)
{
ll ans=0;
while(chain[x]!=chain[y])
{
if(dep[chain[x]]<dep[chain[y]])swap(x,y);
ans+=query(tid[chain[x]],tid[x]);
x=dad[chain[x]];
}
if(tid[x]>tid[y])swap(x,y);
return ans+query(tid[x],tid[y]);
}
ll query_path_max(ll x,ll y)
{
ll ans=-1e9;
while(chain[x]!=chain[y])
{
if(dep[chain[x]]<dep[chain[y]])swap(x,y);
ans=max(ans,query_max(tid[chain[x]],tid[x]));
x=dad[chain[x]];
}
if(tid[x]>tid[y])swap(x,y);
return max(ans,query_max(tid[x],tid[y]));
}
void update_path(ll x,ll y,ll d)
{
while(chain[x]!=chain[y])
{
if(dep[chain[x]]<dep[chain[y]])swap(x,y);
update(tid[chain[x]],tid[x],d);
x=dad[chain[x]];
}
if(tid[x]>tid[y])swap(x,y);
update(tid[x],tid[y],d);
}
void ini()
{
graph::ini();
}
void build()
{
treen=0;
memset(son,-1,sizeof(son));
dfs1();
dfs2();
segment_tree::build(treen);
}
} tree;