[JLOI2014]松鼠的新家(树链剖分)
[JLOI2014]松鼠的新家(luogu)
Description
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。
天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。
可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入格式
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
输出格式
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。
Solution
树链剖分区间加减(注意每次去另一个地方参观终点不用加一个糖果(=+1-1))
Code
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
const int N=3e5+;
vector <int> link[N];
struct node
{
int l,r,lc,rc,tag,d;
}f[N*];
int rt,top[N],si[N],fa[N],tot,cnt,n,u,v,
dfn[N],dep[N],son[N],c[N],q[N],re[N];
void dfs1(int u,int fx)
{
dep[u]=dep[fx]+,fa[u]=fx,si[u]=;
int size=link[u].size();
for(int i=;i<size;i++)
{
int v=link[u][i];
if(v==fx) continue;
dfs1(v,u);
si[u]+=si[v];
if(!son[u] || si[son[u]]<si[v]) son[u]=v;
}
}
void dfs2(int u,int fx)
{
dfn[u]=++tot,re[tot]=u;
if(!son[u]) return ;
top[son[u]]=top[u],dfs2(son[u],u);
int size=link[u].size();
for(int i=;i<size;i++)
{
int v=link[u][i];
if(v==son[u] || v==fx) continue;
top[v]=v,dfs2(v,u);
}
}
void build(int l,int r,int &g)
{
g=++cnt,f[g].l=l,f[g].r=r;
f[g].tag=;
if(l==r)
{
f[g].d=re[l];
return;
}
int mid=(l+r)>>;
build(l,mid,f[g].lc);
build(mid+,r,f[g].rc);
}
void add(int g,int l,int r)
{
if(f[g].l==l && f[g].r==r)
{
f[g].tag++;
return;
}
int mid=(f[g].l+f[g].r)>>;
if(r<=mid) add(f[g].lc,l,r);
else if(l>mid) add(f[g].rc,l,r);
else add(f[g].lc,l,mid),add(f[g].rc,mid+,r);
}
void Add(int x,int y)
{
int px=top[x],py=top[y];
while(px!=py)
if(dep[px]>=dep[py])
{
add(rt,dfn[px],dfn[x]);
x=fa[px],px=top[x];
}
else
{
add(rt,dfn[py],dfn[y]);
y=fa[py],py=top[y];
}
if(dfn[x]<=dfn[y]) add(rt,dfn[x],dfn[y]);
else add(rt,dfn[y],dfn[x]);
}
void push_down(int g)
{
if(f[g].tag==) return ;
f[f[g].lc].tag+=f[g].tag;
f[f[g].rc].tag+=f[g].tag;
f[g].tag=;
}
void dfs(int g)
{
if(f[g].l==f[g].r)
{
c[f[g].d]+=f[g].tag;
return;
}
push_down(g);
dfs(f[g].lc);
dfs(f[g].rc);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&q[i]);
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
link[u].push_back(v);
link[v].push_back(u);
}
dfs1(,);
top[]=,dfs2(,);
build(,tot,rt);
for(int i=;i<=n;i++)
Add(q[i-],q[i]),c[q[i]]--;
dfs(rt);
for(int i=;i<=n;i++)
printf("%d\n",c[i]);
return ;
}
[JLOI2014]松鼠的新家(树链剖分)的更多相关文章
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...
- P3258 [JLOI2014]松鼠的新家 树链剖分
这个题就是一道树剖板子题,就是每走一步就把所有的经过点加一就行了.还有,我的树剖板子没问题!!!谁知道为什么板子T3个点!我不管了!反正这道题正常写A了. 题干: 题目描述 松鼠的新家是一棵树,前几天 ...
- [JLOI2014]松鼠的新家-树链剖分
最开始的时候我在写线段树部分的时候还打了一个build,后来一想,打个球球大作战的build啊!!!有个锤子的用啊!!! #include<bits/stdc++.h> using nam ...
- BZOJ3631 松鼠的新家(树链剖分)
题目链接 松鼠的新家 差不多可以说是树链剖分的模板题了,直接维护即可. #include <bits/stdc++.h> using namespace std; #define REP( ...
- 【BZOJ3631】松鼠的新家 树链剖分
BZOJ3631 松鼠的新家 Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- P3285 松鼠的新家 (树链剖分)
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- BZOJ - 3631 松鼠的新家 (树链剖分)
题目链接 树链剖分基础题,路径权值修改+差分 #include<bits/stdc++.h> using namespace std; typedef long long ll; ; in ...
随机推荐
- windows系统锁屏及修改密码项目开发经验记录
改造windows开机.锁屏登录流程需要使用微软停供的Credential Providers工程,编译出来是dll,安装在C:\windows\system32目录下,然后注册注册表(运行工程生成的 ...
- 在Spring Boot中使用Docker在测试中进行高级功能测试
最近又学到了很多新知识,感谢优锐课老师细致地讲解,这篇博客记录下自己所学所想. 想更多地了解Spring Boot项目中的功能测试吗?这篇文章带你了解有关在测试中使用Docker容器的更多信息. 本文 ...
- 一张图帮你记忆,Spring Boot 应用在启动阶段执行代码的几种方式
前言 有时候我们需要在应用启动时执行一些代码片段,这些片段可能是仅仅是为了记录 log,也可能是在启动时检查与安装证书 ,诸如上述业务要求我们可能会经常碰到 Spring Boot 提供了至少 5 种 ...
- select * from user 这条 SQL 语句,背后藏着哪些不可告人的秘密?
作为一名 Java开发人员,写 SQL 语句是常有的事,但是你知道 SQL 语句背后的处理逻辑吗?比如下面这条 SQL 语句: select * from user where id=1 执行完这条语 ...
- 在win64上使用bypy进行百度网盘文件上传
阿里云服务器的带宽为2M,网站每日的备份包都3G多了,离线下载太费时间了,打算每日将备份包自动上传到自己的百度云盘里.1.先安装Python 执行python -V ,发现没安装python2.去py ...
- DispatcherServlet的url-pattern尽量不要配置为"/*"
DispatcherServlet的url-pattern尽量不要配置为"/*" 原因 当Dispatcher的url配置为"/*"时,会把tomcat的web ...
- key_load_public: invalid format
ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub
- 【转】C#虚方法virtual详解
转:https://www.cnblogs.com/zhaoshujie/p/10502404.html 在C++.Java等众多OOP语言里都可以看到virtual的身影,而C#作为一个完全面向对象 ...
- Netty快速入门(08)ByteBuf组件介绍
前面的内容对netty进行了介绍,写了一个入门例子.作为一个netty的使用者,我们关注更多的还是业务代码.也就是netty中这两种组件: ChannelHandler和ChannelPipeline ...
- JS中如何比较两个数组,取得数组二相对于数组一新增和去除的元素
//数组二相对于数组一所新增的数据 function add_msg(a,b){ return a.filter(function(i){ return b.indexOf(i) === -1 }) ...