题目传送门

  恩,很明显的一个树剖题,配合树上差分其实也并不难,不过无奈蒟蒻树剖还没那么熟练,而且树上差分也做的少,所以这题愣是做了一中午。。。。。。唉,果然我还是太菜了。恩,具体做法在代码中解释吧:

  

//It is made by HolseLee on 6th Jan 2018
//luogu.org
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=;
int n,a[N],c[N],ans[N],head[N],cnt;
int sum,hson[N],size[N],fa[N],id;
int depth[N],top[N],dfn[N],xu[N];
struct Node{
int to,next;
}edge[N<<];
inline int read()//快读
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
inline void add(int x,int y)//加边
{
edge[++cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt;
}
//两个dfs,树剖套路,不解释
inline void dfs1(int u)
{
size[u]=;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u])continue;
depth[v]=depth[u]+;fa[v]=u;
dfs1(v);size[u]+=size[v];
if(!hson[u]||size[v]>size[hson[u]])
hson[u]=v;
}
}
inline void dfs2(int u,int nowtop)
{
dfn[u]=++id;xu[id]=u;top[u]=nowtop;
if(hson[u])dfs2(hson[u],nowtop);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);}
}
inline void lca(int x,int y)//求lca
{
int fax=top[x],fay=top[y];
while(fax!=fay){
if(depth[fax]<depth[fay])
{swap(fax,fay);swap(x,y);}
c[dfn[fax]]++;c[dfn[x]+]--;
   //在深度较浅的点++,较深的点--,差分
x=fa[fax];fax=top[x];
}
if(depth[x]<depth[y])swap(x,y);
c[dfn[y]]++;c[dfn[x]+]--;
   //同上
}
void ready()
{
memset(head,-,sizeof(head));
n=read();
for(int i=;i<=n;i++)
a[i]=read();
for(int i=;i<n;i++){
int x=read();int y=read();
add(x,y);add(y,x);}
  //加边,这里不需要用a数组
  //从样例分析就可以知道,加边的序号是房间原本的编号
depth[]=;fa[]=;
dfs1();dfs2(,);
}
void work()
{
for(int i=;i<n;i++){
int x=a[i],y=a[i+];
lca(x,y);//对每一条路径的起点终点进行操作
c[dfn[y]]--;c[dfn[y]+]++;
}
sum=;
for(int i=;i<=n;i++){
sum+=c[i];
ans[xu[i]]=sum;
  //记录结果,这里注意,不能直接记录ans[i];
  //要用到xu数组;
}
for(int i=;i<=n;i++)
printf("%d\n",ans[i]);
  //输出,完结
return;
}
int main()
{
ready();
work();
return ;
}

  总的来说,这是一道用来练习树剖和树上差分的好题。

洛谷P3258松鼠的新家的更多相关文章

  1. 洛谷 P3258 松鼠的新家 题解

    题面 貌似这道题暴力加玄学优化就可以AC? 下面是正解: 1.树链剖分: 我们在u到v之间都放一个糖果,可以将松鼠它家u到v的糖果数都加1.每一次将a[i]到a[i+1] (a数组是访问顺序)的节点加 ...

  2. 洛谷 [P3258] 松鼠的新家

    树上差分 对于一条路径 \(u->v\) 来说,设 \(t=LCA(u,v)\) ,d[]为差分数组 ,则有 d[u]++;d[v]++;d[t]--;d[fa[t]]--; 注意:题目中所给的 ...

  3. 洛谷P3258 松鼠的新家

    树上差分 这应该是一道很简单的树上差分了..就是问每个点被覆盖了多少次. 要注意我们最后dfs后,要把除第一个节点以外的所有点的-1,因为有些点作为起点和终点覆盖了两次,按照题目意思是不用覆盖两次的. ...

  4. P3258 松鼠的新家

    松鼠的新家 洛谷链接 尽管标签是省选/NOI-,但提交的通过率已经高到三分之一了. 但它仍旧是一个省选/NOI-的题. 大致题意就是按输入的顺序走一棵树,看每个节点经过多少次.问题就相当于把一条链上的 ...

  5. 【题解】P3258松鼠的新家

    [题解][P3258 JLOI2014]松鼠的新家 树链剖分板子题. 总结一点容易写错的地方吧: if(d[top[u]]<d[top[v]]) swap(u,v);注意是\(top\). 在\ ...

  6. Luogu P3258 松鼠的新家(树链剖分+线段树/树状数组)

    题面 题解 这种题目一看就是重链剖分裸题,还是区间修改,单点查询,查询之前在遍历时要记一个\(delta\),因为这一次的起点就是上一次的终点,不需要放糖,所以可以用\(BIT\)来写,但我写完\(m ...

  7. BZOJ3631:[JLOI2014]松鼠的新家——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3631 https://www.luogu.org/problemnew/show/P3258 松鼠的 ...

  8. 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家

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

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

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

随机推荐

  1. 阿里C++研发实习二面和三面面经

    下午连着面了阿里爸爸的二面和三面,非常不明白别人的三面都是hr了,为什么我还是在技术面,难道面了个假阿里.不管怎么样,来篇面经攒攒人品. 二面 第一次遇到这么严肃的面试官,居然可以全程无表情的,面了这 ...

  2. go通过名称来调用对应的方法

    仅仅是为了学习go语言中的反射. package main import ( "errors" "fmt" "reflect" ) func ...

  3. JNLP Slave connection error解决办法

    Replace in jnlp-file  <argument>-workDir</argument>  <argument /> with  <argume ...

  4. MySQL查询 45道练习题

    SQL查询45道练习题 1.查询Student表中的所有记录的Sname.Ssex和Class列.select sname,ssex,class from student2.查询教师所有的单位即不重复 ...

  5. Spring基础使用(一)--------IOC、Bean的XML方式装配

    基础 1.xml文件基础格式: <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns=&q ...

  6. python作业三级菜单day1(第一周)

    一.作业需求: 1. 运行程序输出第一级菜单 2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单 3. 菜单数据保存在文件中 4. 让用户选择是否要退出 5. 有返回上一级菜单的功能 二三级菜单文 ...

  7. 设计模式之Factory

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: Factory Pattern有3种当然是全部是creational pattern. 1.S ...

  8. 64_g4

    gnatcoll-2014-10.fc26.x86_64.rpm 28-Feb-2017 17:44 1738266 gnatcoll-devel-2014-10.fc26.i686.rpm 28-F ...

  9. 【hihocoder】sam-3

    把Parent Tree拓扑排序下,然后从下往上合并. 具体的看官方题解啦~ #include<bits/stdc++.h> #define N 1000010 using namespa ...

  10. freemark学习

    学习地址: http://blog.csdn.net/hejinxu/article/details/6694890   对freemarker的用法与语法进行了详细的讲解 http://freema ...