首页 > 其他分享 >树上差分

树上差分

时间:2024-01-29 20:35:34浏览次数:19  
标签:int 差分 long 100005 fa dev -- 树上

洛谷3128

思路
要进行多次的树上某一段路径的加法操作,暴力做法时间复杂度较大,考虑差分。
对树上路径的两个端点进行操作,在进行遍历的时候将路径的其他点的值还原,从而降低时间复杂度。
注意思路来自董晓算法
代码实现

点击查看代码
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define ll long long
vector<int>v[100005];
int n,k;
int fa[100005][21];
int w[100005]={0};
int dev[100005]={0};
void dfs(int u,int father)
{
    dev[u]=dev[father]+1;
    fa[u][0]=father;
    for(int i=1;i<=20;i++)
    {
        //if(fa[u][i-1]!=0)
      fa[u][i]=fa[fa[u][i-1]][i-1];
    }
    for(int i:v[u])
    {
        if(i==father)
            continue;
        dfs(i,u);

    }

}
int lca(int x,int y)
{
    if(dev[x]<dev[y])
    swap(x,y);
    for(int i=20;i>=0;i--)
    {
        if(dev[fa[x][i]]>=dev[y])
            x=fa[x][i];
    }
    if(x==y)
        return y;
    for(int i=20;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            x=fa[x][i];
            y=fa[y][i];

        }

    }
     return fa[x][0];

}
 int ans=0;
int solve(int u,int fat)
{
    for(int i:v[u])
    {
        if(i==fat)
            continue;
       solve(i,u);
       w[u]+=w[i];
    }

    return w[u];

}
signed main()
{
     cin.tie(NULL);
     cout.tie(nullptr);
     ios_base::sync_with_stdio(false);
     cin>>n>>k;
     for(int i=1;i<=n-1;i++)
     {
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
     }
     dfs(1,0);
     //cout<<lca(4,5)<<" j jj"<<'\n';
     for(int i=1;i<=k;i++)
     {
         int s,t;
         cin>>s>>t;
         int l=lca(s,t);
         w[s]++;
         w[t]++;
         w[l]--;
         w[fa[l][0]]--;
     }
     solve(1,0);
     for(int i=1;i<=n;i++)
        ans=max(w[i],ans);
     cout<<ans;

   return 0;
}

标签:int,差分,long,100005,fa,dev,--,树上
From: https://www.cnblogs.com/wner/p/17995271

相关文章

  • UOJ #33 树上 GCD
    套路地,对每个\(g\in[1,n-1]\)求出有多少对无序对\((u,v)\)满足\(g|f(u,v)\),然后就可以用一个倒序枚举的\(\mathcalO(n\logn)\)的容斥求出答案。考虑点分治,对每个经过分治中心\(c\)的\(u\rightsquigarrow\text{lca}(u,v)\rightsquigarrowv\)只需分两种......
  • 差分数组
    构造差分数组int*constructDifferenceArray(int*nums,intlength){int*diff=(int*)malloc(length*sizeof(int));diff[0]=nums[0];for(inti=1;i<length;i++){diff[i]=nums[i]-nums[i-1];}returndiff;}通过这个diff差分数组是可以反推出原......
  • 【学习笔记】部分树上算法(概念篇)
    本文包括:轻重链剖分(done)线段树合并(done)tobeupd:长链剖分DSUontree(树上启发式合并)点分治边分治LCT有待更新本文非例题代码大多未经过编译,谨慎使用本文本来只有重剖长剖dsu,但是发现不会写,另外几个甚至更简单就带歪了.jpgpart1轻重链剖分树剖是一类算法的总......
  • 【学习笔记】差分约束
    前言2024.1.27\(huge\)在讲不要忽略算法的细节时,以最短路和差分约束为例子。发现自己差分约束忘得差不多了,于是就有了这篇博客。负环在一张图中,若存在一条边权之和为负数的回路,则称这个回路为负环。在一张图中,若存在一条边权之和为正数的回路,则称这个回路为正环。如果一张......
  • 前缀和与差分典题
    includeusingnamespacestd;constintN=1010;inta[N][N],b[N][N];voidinsert(intx1,inty1,intx2,inty2,intc){b[x1][y1]+=c;b[x2+1][y1]-=c;b[x1][y2+1]-=c;b[x2+1][y2+1]+=c;}intmain(){intn,m,q,w;scanf("%d%d%d",&n,&m,&......
  • 1.24 两道树上问题的解法与思考
    内容过于简单,勿喷。1.1P6072Path(双log)选择两条简单路径,满足没有重合的点,且边权异或和之和最大。\(n\le10^5\)。我们可以把问题转化为选出一个\(u\),令在子树内选出两个点的异或和最大为\(f_u\),子树外为\(g_u\),那么我们需要求\(f_u+g_u\)的最大值。首先,通过DSUont......
  • PMP工具与技术-6.1-2 挣值分析、偏差分析、趋势分析
    #######################################################挣值分析其实就是计划完成的内容和花销的预算,与实际完成的内容和花销的预算的对比。其实在PMBOK中搞的有些复杂,我们正常项目中,进度对照进度基准比较,成本对照成本基准比较,就可以了。而挣值相当于是把进度数据*成本数据,......
  • 【scikit-learn基础】--『回归模型评估』之偏差分析
    模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力。本篇主要介绍模型评估时,如何利用scikit-learn帮助我们快速进行各种偏差的分析。1.**R²**分数R²分数(也叫决定系数),用于衡量模型预测的拟合优度,它表示模型中因变量的变异中,可由自变......
  • 浅谈差分约束系统
    差分约束系统前言真的好久好久都没打过这个算法了。当时学的时候学得不明不白,又不写总结、又不刷题(我都不知道自己咋想的),所以今天刷图论题的时候,发现一车子的差分约束都没打过。所以,重学,开写!差分约束系统是什么不要被他名字的学术性吓到了,这个“系统”字面意思理解就行,不是......
  • 优美的暴力——树上启发式合并(dsu on tree)
    dsuontree前言在我认为,这个并不能说单独列出来成为一个算法,更恰当的说,是一种思想、技巧。反正挺简单的,也很有趣(谁会拒绝一个优美的暴力呢),所以写篇笔记记录一手。dsu是什么dsu一般指“disjointsetunion”,即并查集。那么dsuontree也就是指树上的合并和查询操作。但是......