差分

一开始竟然想分情况讨论来差分,然后发现各自情况要分析, 就是为了解决中间节点重复计算的问题, 结果 最后一想,中间重复计算了一次,那我最后减掉不就好了么,,, 那这就是一道差分裸题了(这是唯一不同的地方)

由于是树上差分,所以要先求出所有需要的LCA,然后就是树上差分的套路了

这里由于进来后再出去是只能算一次的,所以略有不同,但实际上也不麻烦,因为直接维护是很困难的,所以不如不维护这个地方,直接在统计答案的时候减掉这些多出来的。

 using namespace std;
#define R register int
#define AC 300100
#define D printf("line in %d\n",__LINE__);
int n,cnt;//cnt是计LCA的
int date[AC*],Next[AC*],Head[AC],tot=;//存图
int qdate[AC*],qNext[AC*],qHead[AC],qtot=;//存询问
int LCA[AC],ans[AC*];//直接按顺序求,所以线性顺序即可
int father[AC],t[AC],power[AC],fa[AC];
bool vis[AC];
//error!!!前向星因为是双向边,然后询问也是双向的,所以这些数组都要*2啊!!!
inline int read()
{
int x=;char c;
while(isspace(c=getchar()));
while(c>='' && c<='')x=x*+c-'',c=getchar();
return x;
} void add1(int f,int w)//加图
{
date[++tot]=w,Next[tot]=Head[f],Head[f]=tot;
date[++tot]=f,Next[tot]=Head[w],Head[w]=tot;
} int find(int x)
{
if(father[x]==x) return x;
else return father[x]=find(father[x]);
} void add2(int f,int w)//加询问
{
qdate[++qtot]=w,qNext[qtot]=qHead[f],qHead[f]=qtot;
qdate[++qtot]=f,qNext[qtot]=qHead[w],qHead[w]=qtot;
} void DFS(int x)
{
R now;
vis[x]=true;
for(R i=Head[x]; i ;i=Next[i])
{
now=date[i];
if(!vis[now])
{
DFS(now);
father[now]=x;//访问完所有的字节点后接上来
}
else fa[x]=now;//不然就是父亲,因为是点权,所以直接等于now就好了
}
for(R i=qHead[x]; i ;i=qNext[i])
{
now=qdate[i];
if(vis[now] && !ans[i ^ ])ans[i]=find(now);
}
} void pre()
{
R a,b;
n=read();
for(R i=;i<=n;i++) t[i]=read();
for(R i=;i<n;i++)
{
a=read(),b=read();
add1(a,b);
}
for(R i=;i<n;i++)//添加询问
add2(t[i],t[i+]);
for(R i=;i<=n;i++)father[i]=i;
DFS();
for(R i=;i<=n*+;i++)
if(ans[i]) LCA[++cnt]=ans[i];
} void getans(int x)//统计答案,可以统计进入
{
R now;
for(R i=Head[x]; i ;i=Next[i])
{
now=date[i];
if(now!=fa[x])
{
getans(now);
power[x]+=power[now];
}
}
} void work()
{
for(R i=;i<n;i++)
{
power[t[i]]++,power[t[i+]]++,power[LCA[i]]--,power[fa[LCA[i]]]--;//由于题目特殊性,不能每次都+1,因为进出房间只是一次
}//但是这样并不好计算,那完全可以直接像平常一样统计啊,由于这样每个中间节点都会被重复计算一次,那输出的时候-1不就好了吗
getans();
for(R i=;i<=n;i++)//因为要按下标输出,但是重复计算的是序列中间的,所以是要序列中间都-1,所以先处理
power[t[i]]--;
for(R i=;i<=n;i++) printf("%d\n",power[i]);
} int main()
{
freopen("in.in","r",stdin);
pre();
work();
fclose(stdin);
return ;
}

[JLOI2014]松鼠的新家 树上差分的更多相关文章

  1. BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA

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

  2. bzoj3631 [JLOI2014]松鼠的新家——树上差分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 树上差分:注意路径的结尾被多算了一次,最后要减去(不能提前减). 代码如下: #inc ...

  3. BZOJ.3631.[JLOI2014]松鼠的新家(树上差分)

    题目链接 树剖/差分裸题.. //28260kb 584ms #include <cstdio> #include <cctype> #include <algorith ...

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

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

  5. BZOJ 3631 松鼠的新家 树上差分

    我猜会有智障说直接链剖+线段树…(希望没有) From RYC's 课件 然鹅我并不反对树剖...我是智障...QAQ 好吧还是树上差分:设 a[i]=u.a[i+1]=v ++w[u],++w[v] ...

  6. [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)

    今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...

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

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

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

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

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

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

随机推荐

  1. Calendar 实现日历实例

    import java.text.ParseException; import java.util.Calendar; import java.util.GregorianCalendar; impo ...

  2. Eclipse - 配置优化

    去除不需要的启动加载项 Window --> Preferences -->General --> Startup and Shutdown 关闭自动更新 Window --> ...

  3. andriod学习二 设置开发环境

    1.官方环境搭建步骤     http://developer.android.com/sdk/installing/index.html         包括:下载JDK6,Eclipse 3.6, ...

  4. Xuan.UWP.Framework(2)

    上一章主要介绍了Xuan.UWP.Framework.ImageLib的基本用法,这一章具体来看些Xuan.UWP.Framework.ImageLib的使用. 一.首先看下Xuan.UWP.Fram ...

  5. Linux命令应用大词典-第16章 归档和压缩

    16.1 tar:进行归档和压缩 16.2 gzip:压缩或解压缩gzip文件 16.3 gunzip:解压缩gzip文件 16.4 zcmp:比较gzip压缩文件 16.5 zdiff:比较gzip ...

  6. Linux命令应用大词典-第7章 字符串、文件和命令查找

    7.1 grep:字符串.文件和命令的查找 7.2 egrep:在文件或标准输入中查找模式 7.3 fgrep:在每个文件或是标准输入中查找模式 7.4 find:列出文件系统内符合条件的文件 7.5 ...

  7. 【system.string】使用说明

    对象:system.string 说明:提供一系列针对字符串类型的操作 目录: 方法 返回 说明 system.string.isBlank( string ) [True | False]  检测参 ...

  8. LeetCode - 231. Power of Two - 判断一个数是否2的n次幂 - 位运算应用实例 - ( C++ )

    1.题目:原题链接 Given an integer, write a function to determine if it is a power of two. 给定一个整数,判断该整数是否是2的 ...

  9. nordic mesh 任务调度实现

    nordic mesh 任务调度实现 nordic mesh的任务调度室基于定时器实现的,有两个链表结构维护任务. 需要注意的是,任务调度的部分接口只能在"bearer event" ...

  10. 团队协作第八周个人PSP

    11.3 --11.9本周例行报告 1.PSP(personal software process )个人软件过程. 类型 任务 开始时间                结束时间 中断时间 实际用时 ...