[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 ...
随机推荐
- easypermissions拒绝权限后闪退。 java.lang.NoSuchMethodError: No virtual method isStateSaved()Z in class Landroid/support/v4/app/FragmentManager
Process: com.tazan.cd.streetlight, PID: 18825 java.lang.NoSuchMethodError: No virtual method isState ...
- Popup a window before the MainWindow
protected override void OnStartup(StartupEventArgs e) { Window w = new Window(); w.ShowDialog(); bas ...
- c++修改系统环境变量 (修改注册表以后,立刻使用SendMessageTimeout(HWND_BROADCAST进行广播)
#include "stdafx.h" #include "addPath.h" #define _AFXDLL #include <afxwin.h&g ...
- Perl中的bless的理解
bless有两个参数:对象的引用.类的名称. 类的名称是一个字符串,代表了类的类型信息,这是理解bless的关键. 所谓bless就是把 类型信息 赋予 实例变量. [xywang@mnsdev13: ...
- 关于C#异步编程你应该了解的几点建议
前段时间写了一篇关于C#异步编程入门的文章,你可以点击<C#异步编程入门看这篇就够了>查看.这篇文章我们来讨论下关于C#异步编程几个不成文的建议,希望对你写出高性能的异步编程代码有所帮助. ...
- 空气质量管理系统ssm(mybatis+spring+springMVC)框架+前后端分离
1.目录结构: 2.需要注意的地方 2.1在WEB-INFO下新建 2.1.1 springMVC-servlet.xml <?xml version="1.0" encod ...
- npm脚本和package.json
1.什么是npm脚本 在创建node.js项目如一个vue项目,或一个react项目时,项目都会生成一个描述文件package.json . 比如npm允许在package.json文件里面,使用sc ...
- iptables脚本封ip
##自动封IP:分析web或应用日志或者网络连接状态封掉垃圾IP #!/bin/sh /bin/netstat -na|grep ESTABLISHED|awk |grep -v -E '192.16 ...
- 深度探索c++对象模型阅读笔记图
- 从零开始のcocos2dx生活(二)Node
节点 Node 文章目录 节点 Node 前言 变量初始化 创建一个节点对象 获取节点依赖的计数器 获取节点的描述(获取节点的Tag) 节点的局部层顺序值(LocalZOrder) 设置节点的Loca ...