首页 > 其他 > 详细

树上差分

时间:2020-06-27 22:33:08      阅读:76      评论:0      收藏:0      [点我收藏+]

差分

如果去看我的树状数组的博客的话就懂了,就是记录相邻节点值的差值。这样一来,前缀和就相当于原值了。

树上差分

树上差分基本上就是差分在树上的实现。因为差分的原理,我们先将所有点的权值改变成差分值,再更改一段区间内的所有值时,只需要更改首尾两端的值,如果要求值的话dfs重新加上前缀和就是正常的值了。

模板:洛谷P3128

模板题,发现更改任意两点间的值只需要在两点差分值加上1然后在lca和fa[lca](倍增的话就是fa[lca][0])上减去1,从根dfs并记录最大值即可。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<ctype.h>
#define R register
using namespace std;
inline int read()
{
    int x=0,w=0;char c=getchar();
    while(!isdigit(c))w|=c==-,c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return w?-x:x;
}
const int maxn=233333;
int n,m,ans[maxn];
int top[maxn],fa[maxn][18],dep[maxn],head[maxn],ecnt,cnt;
struct Edge{
    int to,nxt;
}e[maxn<<1];
inline void addedge(int a,int b)
{
    e[++ecnt]=(Edge){b,head[a]};head[a]=ecnt;
    e[++ecnt]=(Edge){a,head[b]};head[b]=ecnt;
}
bool vis[maxn];
void dfs1(int x,int depth)
{
    for (R int i=0;fa[x][i];++i) fa[x][i+1]=fa[fa[x][i]][i];
    vis[x]=1;
    dep[x]=depth;
    for(R int i=head[x];i;i=e[i].nxt)
    {
        int u=e[i].to;
        if(vis[u])continue;
        fa[u][0]=x;
        dfs1(u,depth+1);
    }
}
inline int LCA(int u,int v)
{
    if(dep[u]<dep[v])swap(u,v);
    for(R int i=0;i<=16;i++)
        if((dep[u]-dep[v])&(1<<i))u=fa[u][i];
    if(u==v)return u;
    for(R int i=16;i>=0;i--)
        if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
    return fa[u][0];
 } 
 int Ans=0;
void dfs2(int x)
{
    vis[x]=1;
    for(R int i=head[x];i;i=e[i].nxt)
    {
        int u=e[i].to;
        if(vis[u])continue;
        dfs2(u);
        ans[x]+=ans[u];
    }
    Ans=max(Ans,ans[x]);
}
int main()
{
    n=read(),m=read();
    for(R int i=1;i<n;i++)addedge(read(),read());
    fa[1][0]=0;
    dfs1(1,1);
    for(R int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        int lca=LCA(x,y);
        ans[x]++,ans[y]++,ans[lca]--,ans[fa[lca][0]]--; 
    }
    memset(vis,0,sizeof vis); 
    dfs2(1);
    printf("%d\n",Ans);
    return 0;
}

 

树上差分

原文:https://www.cnblogs.com/BrotherHood/p/13200165.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!