今天算是把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. 【Android Developers Training】 25. 保存文件

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  2. Java - 在WebService中使用Client调用三方的RestAPI

    背景 近期,由于项目的要求需要在自己的webservice中调用远程的WebAPI(Restful format).自己的webservice程序是用Java编码写的,所以需要在其中实现一个Clien ...

  3. Linux 多用户系统

    Linux OS是基于Unix系统开发而来,我们知道计算机是昂贵与稀缺的资源,所以一台计算机就要满足多个用户同时使用,即多用户的系统的思想. 实现方式:通过分时共享的策略.即让多个用户可以同时使用一台 ...

  4. python中json.loads,dumps,jsonify使用

    search_info = {'id':132,'user_role':3} print type(search_info) #输出 <type 'dict'> #转为string用dum ...

  5. [转]ubuntu搭建LAMP环境

    首先下载安装apache2 输入:sudo apt-get install apache2 安装完毕后,在浏览器中输入:localhost 可以看到apache的默认主页 紧接着安装php5 输入:s ...

  6. vijos1051题解

    题目: 圣诞老人回到了北极圣诞区,已经快到12点了.也就是说极光表演要开始了.这里的极光不是极地特有的自然极光景象.而是圣诞老人主持的人造极光. 轰隆隆--烟花响起(来自中国的浏阳花炮之乡).接下来就 ...

  7. Ajax获取数据的几种格式和解析方式

    一.什么是ajax  AJAX的全称是Asynchronous JavaScript and XML(是异步的 javascript 和 XML).  ajax不是新的编程语言,而是一种使用现有标准的 ...

  8. MySQL 'localhost' (10061)解决方法

    今天启动mysql 出现10061错误,处理:修改hosts文件中localhost指向127.0.0.1. 参看:http://www.cnblogs.com/ljian/archive/2011/ ...

  9. Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法

    当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的python类,负责接收到item并通过它执行一些行为, ...

  10. 关于"模块计算机类型与目标计算机类型冲突"的解决

    问题描述:我的64位工程包含32位静态库之后报错(模块计算机类型"x86"与目标计算机类型"x64"冲突),将工程修改为32位之后,又报错(若干个无法解析的外部 ...