今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分。其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过。

我们先来把树上差分能做到的看一下:

1.找所有路径公共覆盖的边

例题:[NOIP2015]运输计划 (然而我还没过就先不讲了)

反正就是中间有一步要求一条边被所有计划公共覆盖。

那么怎么求它呢?暴力(滚粗)。我们有一个非常好的方法就是树上差分(记录tmp为差分数组)

询问操作为从叶子节点的权值向上累加到root

在一条路径u→ v,如果tmp[u]++,那么我们往上推的时候相当于u到root所有路径都被访问一次。同理tmp[v]++也意味如此。但是,lca(u,v)到root的路径都没有被访问过,但这里都被标记过两次,所以我们还要做的操作就是tmp[lca(u,v)]-=2;这样的话累加完之后tmp[i]记录的就是i节点被多少条路径覆盖了。

2.将路径上的所有点权值+1,最后求点权

例题:[JLOI2014]松鼠的新家 (这个我做过了hhh)

题目大意就是给你一些路径,把这个路径经过的点权+1,最后求所有点权。

这个题今天卡了我了。同学大佬有拿树剖求的,而且还要差分。但是我对于树上差分有点蒙蔽,于是搜了搜。然而蒟蒻的我搜到了LCA解法,于是兴高采烈的打(chao)了(le)出来。这里的差分有一些不同。因为我们要找的是点的覆盖。所以我们对于u→ v,tmp[u]++,tmp[v]++,tmp[lca(u,v)]--,tmp[fa[lca(u,v)]]--;这个想必大家能看懂吧。

于是,我们就欢快的求出了所有点被修改后的权值。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
#define N 301000
struct haha{
    int next,to;
}edge[N*2];
int head[N],cnt=1,p[N][20];
void add(int u,int v){
    edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;
}
int a[N],n,fa[N],dep[N];
void dfs(int x){
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(fa[x]!=to){
            fa[to]=x;dep[to]=dep[x]+1;
            dfs(to);
        }
    }
}
void init(){
    int j;
    for(j=0;(1<<j)<=n;j++){
        pos(i,1,n) p[i][j]=-1;
    }
    pos(i,1,n){
        p[i][0]=fa[i];
    }
    for(j=1;(1<<j)<=n;j++){
        pos(i,1,n){
            if(p[i][j-1]!=-1){
                p[i][j]=p[p[i][j-1]][j-1];
            }
        }
    }
}
int lca(int a,int b){
    int i;
    if(dep[a]<dep[b]) swap(a,b);
    for(i=0;(1<<i)<=dep[a];i++);
    i--;
    for(int j=i;j>=0;j--)
        if(dep[a]-(1<<j)>=dep[b])
            a=p[a][j];
    if(a==b) return a;
    for(int j=i;j>=0;j--){
        if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
            a=p[a][j];b=p[b][j];
        }
    }
    return fa[a];
}
int tmp[N];
void work(int x){
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(fa[x]!=to){
            work(to);
            tmp[x]+=tmp[to];
        }
    }
}
int main(){
    scanf("%d",&n);
    pos(i,1,n)
        scanf("%d",&a[i]);
    pos(i,1,n-1){
        int x,y;scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    dfs(a[1]);
    init();
    pos(i,1,n-1){
        int u=a[i],v=a[i+1];
        tmp[u]++;tmp[v]++;
        tmp[lca(u,v)]--;tmp[fa[lca(u,v)]]--;
    }
    work(a[1]);
    pos(i,2,n) tmp[a[i]]--;
    pos(i,1,n) printf("%d\n",tmp[i]);
    return 0;
}

  

[填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)的更多相关文章

  1. [JLOI2014] 松鼠的新家 (lca/树上差分)

    [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...

  2. P3258[JLOI2014]松鼠的新家(LCA 树上差分)

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  3. 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...

  4. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

    [题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...

  5. luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)

    P3258 [JLOI2014]松鼠的新家  题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...

  6. [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2350  Solved: 1212[Submit][Sta ...

  7. 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...

  8. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  9. [Luogu 3258] JLOI2014 松鼠的新家

    [Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...

随机推荐

  1. iOS9新特性之常见关键字、泛型

    #pragma mark -- nullable nullable:可以为空,只能修饰对象,不能修饰基本数据类型 // 方式一: @property (nonatomic, copy, nullabl ...

  2. AngularJS服务和路由

    colnplie     网页加载的出现一次 link     元素每次改变的时候 **$watch** 监听列表     $scope.$watch("name",functio ...

  3. 使用Homebrew配置Java开发环境

    查询java brew cask search java 查看版本信息 brew cask info java 从官网下载并安装 JDK 8 brew cask install java 需要安装 J ...

  4. Jenkins 配置邮件通知

    jenkins 是一个开源的自动化服务器.通过Jenkins,可以通过自动化加速软件开发过程.Jenkins管理和控制各种开发的生命周期过程,包括构建,文档,测试,包,阶段,部署,静态分析等等.您可以 ...

  5. XManager与SecureCRT

    使用Xmanager前,服务器必须已经安装好X11所需的各种运行包.运行下列命名检查安装情况,没有的话请自行补上. rpm -qa|grep x11 1.DISPLAY环境变量 export DISP ...

  6. VB6之ICMP实现ping功能

    代码备忘 'code by lichmama from cnblogs.com Private Type IPAddr ip1 As Byte ip2 As Byte ip3 As Byte ip4 ...

  7. poj3276

    Face The Right Way Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5121   Accepted: 237 ...

  8. .NetCore~Json代替了Xml

    回到目录 在进行.netCore时代后,最大的变化就是对Json的使用更加主动,基本代替了之前的XML,像一些用户配置,系统配置,包包配置等都是基于json的,而web.config这个文件基本变成一 ...

  9. asp.net验证码的编写

    很多时候我们在登录什么网站的时候,除了需要什么用户名和密码之外,有的还需要验证码那么在asp.net中这个验证码如何编写和设计,今天我就来给大家说一下: 首先创建一个页面名字随便起一个,我们这里叫做C ...

  10. IScroll那些事——内容不足时下拉刷新

    之前项目中的列表是采用的IScroll,但是在使用IScroll有一个问题就是:当内容不足全屏的时候,是木有办法往下拉的,这样就达不到刷新的目的了.[这是本人工作中遇到的,具体例子具体分析,这里只作一 ...