题目描述

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

松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

输入输出格式

输入格式:

第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an

接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

输出格式:

一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。

思路:

又是一道树剖板子题

对于小熊的访问,我们可以看成是从在a[i]~a[i+1]的路径上都增加了1

然后由于有重复,将每次将a[i+1]减1就好

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<queue>
#include<algorithm>
//#define int long long
#define rii register int i
#define rij register int j
using namespace std;
int n;
struct ljb{
int to,nxt;
}x[];
struct node{
int val,lazy;
}y[];
int f[],sd[],head[],val[],size[];
int weison[],cnt,bnt,nid[],nval[],ntop[];
int sx[];
int res;
void add(int from,int to)
{
cnt++;
x[cnt].to=to;
x[cnt].nxt=head[from];
head[from]=cnt;
}
void dfs1(int wz,int fa,int s)
{
sd[wz]=s;
f[wz]=fa;
size[wz]=;
int maxn=;
for(rii=head[wz];i!=;i=x[i].nxt)
{
int to=x[i].to;
if(to==fa)
{
continue;
}
dfs1(to,wz,s+);
size[wz]+=size[to];
if(size[to]>maxn)
{
maxn=size[to];
weison[wz]=to;
}
}
}
void dfs2(int wz,int top)
{
bnt++;
nid[wz]=bnt;
nval[bnt]=val[wz];
ntop[wz]=top;
if(weison[wz]==)
{
return;
}
dfs2(weison[wz],top);
for(rii=head[wz];i!=;i=x[i].nxt)
{
int to=x[i].to;
if(weison[wz]==to||f[wz]==to)
{
continue;
}
dfs2(to,to);
}
}
void build(int bh,int l,int r)
{
if(l==r)
{
y[bh].val=nval[l];
return;
}
int mid=(l+r)/;
build(bh*,l,mid);
build(bh*+,mid+,r);
y[bh].val+=y[bh*].val+y[bh*+].val;
}
void pushdown(int bh,int cd)
{
y[bh*].lazy+=y[bh].lazy;
y[bh*+].lazy+=y[bh].lazy;
y[bh*].val+=y[bh].lazy*(cd-(cd/));
y[bh*+].val+=y[bh].lazy*(cd/);
y[bh].lazy=;
}
void updata(int bh,int nl,int nr,int l,int r,int val)
{
int len=(nr-nl+);
if(l<=nl&&nr<=r)
{
y[bh].lazy+=val;
y[bh].val+=val*len;
return;
}
if(y[bh].lazy!=)
{
pushdown(bh,len);
}
int mid=(nl+nr)/;
if(l<=mid)
{
updata(bh*,nl,mid,l,r,val);
}
if(r>mid)
{
updata(bh*+,mid+,nr,l,r,val);
}
y[bh].val=(y[bh*].val+y[bh*+].val);
}
void query(int bh,int nl,int nr,int l,int r)
{
if(l<=nl&&r>=nr)
{
res+=y[bh].val;
return;
}
int mid=(nl+nr)/;
if(y[bh].lazy!=)
{
pushdown(bh,nr-nl+);
}
if(l<=mid)
{
query(bh*,nl,mid,l,r);
}
if(r>mid)
{
query(bh*+,mid+,nr,l,r);
}
}
int querylj(int from,int to)
{
int ans=;
while(ntop[from]!=ntop[to])
{
if(sd[ntop[from]]<sd[ntop[to]])
{
swap(from,to);
}
res=;
query(,,n,nid[ntop[from]],nid[from]);
ans+=res;
from=f[ntop[from]];
}
if(sd[from]>sd[to])
{
swap(from,to);
}
res=;
query(,,n,nid[from],nid[to]);
ans+=res;
return ans;
}
void addlj(int from,int to,int val)
{
while(ntop[from]!=ntop[to])
{
if(sd[ntop[from]]<sd[ntop[to]])
{
swap(from,to);
}
updata(,,n,nid[ntop[from]],nid[from],val);
from=f[ntop[from]];
}
if(sd[from]>sd[to])
{
swap(from,to);
}
updata(,,n,nid[from],nid[to],val);
}
signed main()
{
scanf("%d",&n);
for(rii=;i<=n;i++)
{
scanf("%d",&sx[i]);
}
for(rii=;i<n;i++)
{
int fe,to;
scanf("%d%d",&fe,&to);
add(fe,to);
add(to,fe);
}
dfs1(,,);
dfs2(,);
build(,,n);
for(rii=;i<n;i++)
{
addlj(sx[i],sx[i+],);
addlj(sx[i+],sx[i+],-);
}
for(rii=;i<=n;i++)
{
printf("%d\n",querylj(i,i));
}
}

[JLOI2014]松鼠的新家(线段树,树链剖分)的更多相关文章

  1. Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...

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

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

  3. BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )

    裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...

  4. 树链剖分 [JLOI2014]松鼠的新家

    [JLOI2014]松鼠的新家 时间限制: 1 Sec  内存限制: 128 MB 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达, ...

  5. [JLOI2014]松鼠的新家(树链剖分)

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

  6. [JLOI2014]松鼠的新家 (树剖)

    题目 P3258 [JLOI2014]松鼠的新家 解析 非常裸的一道树剖题 链上修改+单点查询的板子 记录一下所经过的点\(now[i]\),每次更新\(now[i-1]到now[i]\) 我们链上更 ...

  7. 3631: [JLOI2014]松鼠的新家

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 707  Solved: 342[Submit][Statu ...

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

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

  9. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

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

随机推荐

  1. html5 移动端开发

    移动端开发总结     目录 1.手机与浏览器 2.Viewport(视窗) 3. 媒体查询 4.px,em,rem,pt 5.设备像素比devicePixelRatio 6.移动web中的图标及字体 ...

  2. Android adb命令查看sharedpreferences

    adb shell run-as com.example.android //对应包名 ls查看当前目录下的所有文件,找到shared_prefs cd shared_prefs ls 查看所有的 s ...

  3. Android Editable

    在android的sdk中有讲,“This is the interface for text whose content and markup can be changed (as opposed ...

  4. css预处理器(sass)

    学过CSS的人都知道,它不是一种编程语言.你可以用它开发网页样式,但是没法用它编程.也就是说,CSS基本上是设计师的工具,不是程序员的工具.在程序员眼里,CSS是一件很麻烦的东西.它没有变量,也没有条 ...

  5. 利用dotnet restore 导入本地 .nupkg 包

    dotnet restore 主要是用于部署.net core 项目中所需的依赖库,集成了nuget包管理软件.因此,dotnet restore 实际上就是根据project.json(今后可能为p ...

  6. Mac系统查看端口占用和杀死进程

    查看进程占用 lsof -i tcp:8080 该命令会显示占用8080端口的进程,有其 pid ,可以通过pid关掉该进程 杀死进程 kill pid 例如 kill 39394 转自:https: ...

  7. Python logger模块

    1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...

  8. 7 Dockerfile指令详解 && VOLUME 指令

    格式为: VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径> 之前我们说过,容器运行时应该尽量 ...

  9. Asp.Net MVC Identity 2.2.1 使用技巧(七)

    创建角色管理相关视图 1.添加视图 打开RolesAdminController.cs   将鼠标移动到public ActionResult Index()上  右键>添加视图   系统会弹出 ...

  10. jq模仿h5 placeholder效果

    $(".pay-license input").on("input propertychange blur",function(){ if($(this).va ...