洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家
题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入输出格式
输入格式:
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
输出格式:
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。
输入输出样例
5
1 4 5 3 2
1 2
2 4
2 3
4 5
1
2
1
2
1
说明
2<= n <=300000
解题思路
树链剖分,几乎和USACO的某题一毛一样,不同之处在于,这题路径中途的点会重复计算,输出结果不为零时要减一,而且最后一个点不用放糖果。
我写的树剖+线段树,常数贼大,洛谷上不开O2的话#4就跑不过,可能树剖+树状数组,或者把结构体拆成数组会好一些。正解是树上差分,不会……
源代码
#include<bits/stdc++.h>
int n;
struct Edge{
int nxt,to;
}e[];
int head[]={},cnt=;
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
e[cnt]={head[v],u};
head[v]=cnt++;
}
struct Tree{
int fa;
int dep;
int num_to;
int wson;
int new_id;
int top;
}t[];
int id=;
void dfs1(int fa,int u,int dep)
{
t[u].fa=fa;
t[u].dep=dep;
t[u].num_to=;
t[u].wson=-;
int max_to=,num_son=;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa) continue;
num_son++;
dfs1(u,v,dep+);
int temp=t[v].num_to;
t[u].num_to+=temp;
if(temp>max_to) t[u].wson=v,max_to=temp;
}
}
void dfs2(int u,int top)
{
t[u].top=top;
t[u].new_id=id;
id++;
if(t[u].wson==-) return;
dfs2(t[u].wson,top);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==t[u].fa||v==t[u].wson) continue;
dfs2(v,v);
}
}
#define lson(x) ((x)<<1)
#define rson(x) ((x)<<1|1)
struct Seg_tree{
int l,r;
int sum;
}s[];
int lazy[]={};
void pushdown(int x)
{
int temp=lazy[x];
lazy[x]=;
int ls=lson(x),rs=ls|;
s[ls].sum+=temp*(s[ls].r-s[ls].l+);
lazy[ls]+=temp;
s[rs].sum+=temp*(s[rs].r-s[rs].l+);
lazy[rs]+=temp;
}
void maketree(int x,int l,int r)
{
s[x].l=l,s[x].r=r;
if(l==r)
{
s[x].sum=;
return;
}
int mid=l+r>>;
maketree(lson(x),l,mid);
maketree(rson(x),mid+,r);
s[x].sum=;
}
void update(int x,int l,int r,int k)
{
if(s[x].l>r||s[x].r<l) return;
if(l<=s[x].l&&s[x].r<=r)
{
s[x].sum+=k*(s[x].r-s[x].l+);
lazy[x]+=k;
return;
}
if(lazy[x]) pushdown(x);
update(lson(x),l,r,k);
update(rson(x),l,r,k);
s[x].sum=s[lson(x)].sum+s[rson(x)].sum;
}
int query(int x,int l,int r)
{
if(s[x].l>r||s[x].r<l) return ;
if(l<=s[x].l&&s[x].r<=r)
return s[x].sum;
if(lazy[x]) pushdown(x);
return query(lson(x),l,r)+query(rson(x),l,r);
}
void add_path(int x,int y)
{
while(t[x].top!=t[y].top)
{
if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
int xtop=t[x].top;
update(,t[xtop].new_id,t[x].new_id,);
x=t[xtop].fa;
}
if(t[x].new_id<t[y].new_id) std::swap(x,y);
update(,t[y].new_id,t[x].new_id,);
}
int a[]={};
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
dfs1(,,);
dfs2(,);
maketree(,,n);
for(int i=;i<n;i++)
add_path(a[i],a[i+]);
for(int i=;i<=n;i++)
{
int ans=query(,t[i].new_id,t[i].new_id);
if(ans==||i==a[]);
else ans--;
printf("%d\n",ans);
}
return ;
}
吐槽
退役后暑假一个月没碰电脑了,即将进入高三,在开学前夜最后做一道题吧,可能一直到高考这283天都不能刷题了……伤心……
手有些生疏了,敲了5个小时。但是退役前也要敲好久来着。码力不够,思考、敲代码速度太慢,也难怪OI大赛一直不顺了。
拼一把高考,把OI先放一放,等拼到不错的大学,ACM时再重新拾起吧!
洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家的更多相关文章
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- bzoj 3631: [JLOI2014]松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ.3631.[JLOI2014]松鼠的新家(树上差分)
题目链接 树剖/差分裸题.. //28260kb 584ms #include <cstdio> #include <cctype> #include <algorith ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- 3631. [JLOI2014]松鼠的新家【树形DP】
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2350 Solved: 1212[Submit][Sta ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
随机推荐
- 洛谷 P3806 点分治模板
题目:https://www.luogu.org/problemnew/show/P3806 就是点分治~ 每次暴力枚举询问即可,复杂度是 nmlogn: 注意 tmp[0]=1 ! 代码如下: #i ...
- Spark 机器学习------逻辑回归
package Spark_MLlib import javassist.bytecode.SignatureAttribute.ArrayType import org.apache.spark.s ...
- MySQL 1071错误解决办法
今天在使用mysql时,又遇到了如博文标题所示的问题,以前针对该问题未进行记录,今天特意进行说明存档. 该问题是由键值字段长度过长导致.mysql支持数据库表单一键值的最大长度不能超过 ...
- 9.23 NOIP模拟题(数学专练)
数论基础 专题测试 命题人:清华大学 王赢绪 /* 水题 答案为C(n-k,m-1) 预处理阶乘和逆元,O(1)算答案 开始读错题了!!!朱一乐!!! */ #include<iostream ...
- 基于docker的tomcat服务化
tomcat作为web容器被广泛应用,但作者所在的公司restful接口特别多,每个接口都需要一个tomcat来启动,为了配置隔离,一般都会把tomcat安装文件复制多遍,分别把war包部署在对应的w ...
- 【学习笔记】OI玄学道—代码坑点
[学习笔记]\(OI\) 玄学道-代码坑点 [目录] [逻辑运算符的短路运算] [\(cmath\)里的贝塞尔函数] 一:[逻辑运算符的短路运算] [运算规则] && 和 || 属于逻 ...
- 了解MySQL的字符集
在数据库中,字符乱码属于常见.多发问题.鉴于本人水平顶多只能归于不入流之类,写这篇文章时内心诚惶诚恐,实在担心误导大家.内容仅供参考,若有错误,请各位及时指出,我也好学习提高! MySQL的字符集有4 ...
- 关于BUG
1.BUG的理解 2.提高BUG report的技巧
- Java系列学习(九)-多态
1.final关键字 (1)最终的意思, 可以修饰类,方法,变量 (2)特点: A:它修饰的类,不能被继承 B:它修饰的方法,不能被重写(覆盖) C:它修饰的变量,这个变量其实是一个常量 [扩展] ① ...
- [Windows Server 2012] MySQL安全加固
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:MySQL ...