[JLOI2014]松鼠的新家(线段树,树链剖分)
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有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]松鼠的新家(线段树,树链剖分)的更多相关文章
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 树链剖分 [JLOI2014]松鼠的新家
[JLOI2014]松鼠的新家 时间限制: 1 Sec 内存限制: 128 MB 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达, ...
- [JLOI2014]松鼠的新家(树链剖分)
[JLOI2014]松鼠的新家(luogu) Description 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间 ...
- [JLOI2014]松鼠的新家 (树剖)
题目 P3258 [JLOI2014]松鼠的新家 解析 非常裸的一道树剖题 链上修改+单点查询的板子 记录一下所经过的点\(now[i]\),每次更新\(now[i-1]到now[i]\) 我们链上更 ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
随机推荐
- Architecture And Framework
高屋建瓴 From Up to Down. Outside into inside. Interface-Oriented Framework with dynamic configuration. ...
- Monkey测试环境搭建
一.JAVA环境的搭建 1.安装jdk-7u60-windows-x64(JAVA1.7.0,也可安装最新版的JAVA1.8.0),默认安装路径C盘: 2.JAVA环境变量的搭建: 我的电脑→右键属性 ...
- JS 日期与时间戳相互转化
1.日期格式转时间戳 function getTimestamp(time) { return Date.parse(new Date(time)); } 2.时间戳转日期格式 function tr ...
- UX基础 - OmniGraffle新手指南
原文地址:http://beforweb.com/node/202,大半夜找到,作为使用手册 我发现一事儿,就是最近这些年,每到入职一个新公司的时候,听得东西往往会比多数时候听得更重更金属些,此时以S ...
- malloc()函数,calloc()函数,realloc()函数,free()函数
malloc()函数 头文件:#include <stdlib.h> malloc() 函数用来动态地分配内存空间,其原型为:void* malloc (size_t size); [参数 ...
- 初识Spark程序
执行第一个spark程序 普通模式提交任务: bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master spark ...
- 进程间通信——队列和管道(multiprocess.Queue、multiprocess.Pipe)
进程: 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运 ...
- Python学习---JSON学习180130
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javascript对象: Json字符串就是js对象的一种表现形式(字符串的形式 ...
- 编码学习---代码OJ网站
代码OJ网站: https://leetcode-cn.com/accounts/login/
- Nginx学习---Nginx的详解_【all】
1.1. Nginx简介 1.什么是nginx nginx:静态的,开源的www软件,可以解析静态的小文件(低于1M ),支持高并发占用较发少的资源(3W并发,10个进程,内存150M),跨平台 te ...