洛谷P3258松鼠的新家
恩,很明显的一个树剖题,配合树上差分其实也并不难,不过无奈蒟蒻树剖还没那么熟练,而且树上差分也做的少,所以这题愣是做了一中午。。。。。。唉,果然我还是太菜了。恩,具体做法在代码中解释吧:
//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松鼠的新家的更多相关文章
- 洛谷 P3258 松鼠的新家 题解
		题面 貌似这道题暴力加玄学优化就可以AC? 下面是正解: 1.树链剖分: 我们在u到v之间都放一个糖果,可以将松鼠它家u到v的糖果数都加1.每一次将a[i]到a[i+1] (a数组是访问顺序)的节点加 ... 
- 洛谷 [P3258] 松鼠的新家
		树上差分 对于一条路径 \(u->v\) 来说,设 \(t=LCA(u,v)\) ,d[]为差分数组 ,则有 d[u]++;d[v]++;d[t]--;d[fa[t]]--; 注意:题目中所给的 ... 
- 洛谷P3258 松鼠的新家
		树上差分 这应该是一道很简单的树上差分了..就是问每个点被覆盖了多少次. 要注意我们最后dfs后,要把除第一个节点以外的所有点的-1,因为有些点作为起点和终点覆盖了两次,按照题目意思是不用覆盖两次的. ... 
- P3258 松鼠的新家
		松鼠的新家 洛谷链接 尽管标签是省选/NOI-,但提交的通过率已经高到三分之一了. 但它仍旧是一个省选/NOI-的题. 大致题意就是按输入的顺序走一棵树,看每个节点经过多少次.问题就相当于把一条链上的 ... 
- 【题解】P3258松鼠的新家
		[题解][P3258 JLOI2014]松鼠的新家 树链剖分板子题. 总结一点容易写错的地方吧: if(d[top[u]]<d[top[v]]) swap(u,v);注意是\(top\). 在\ ... 
- Luogu P3258 松鼠的新家(树链剖分+线段树/树状数组)
		题面 题解 这种题目一看就是重链剖分裸题,还是区间修改,单点查询,查询之前在遍历时要记一个\(delta\),因为这一次的起点就是上一次的终点,不需要放糖,所以可以用\(BIT\)来写,但我写完\(m ... 
- BZOJ3631:[JLOI2014]松鼠的新家——题解
		http://www.lydsy.com/JudgeOnline/problem.php?id=3631 https://www.luogu.org/problemnew/show/P3258 松鼠的 ... 
- 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家
		题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ... 
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
		P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ... 
随机推荐
- 整数中1出现的次数(从1到n整数中1出现的次数)
			整数中1出现的次数(从1到n整数中1出现的次数) 题目描述 求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1.10 ... 
- Eclipse Support UTF-8
			1. Windows > Preferences > General > Content Types, set UTF-8 as the default encoding for ... 
- 一道lambda表达式题目
			#include <iostream> #include <functional> using namespace std; auto Pair = [](auto u, au ... 
- 【BZOJ3884】上帝与集合的正确用法 [欧拉定理]
			上帝与集合的正确用法 Time Limit: 5 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 第一行一个T ... 
- 【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
			[算法]DP+数学优化 [题意]把n个1~m的数字分成k段,每段的价值为段内不同数字个数的平方,求最小总价值.n,m,ai<=40000 [题解] 参考自:WerKeyTom_FTD 令f[i] ... 
- 【51NOD-0】1049 最大子段和
			[算法]DP [题解]开long long…… #include<cstdio> #include<algorithm> #include<cstring> usi ... 
- python学习笔记(七)之列表
			列表:是一个加强版的数组,什么东西都可以往里面放. 创建列表 创建一个普通列表: >>> member = ['operating system', 'data structure' ... 
- HDU  1284    钱币兑换问题   (dp)
			题目链接 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于327 ... 
- 利用最新Apache解析漏洞(CVE-2017-15715)绕过上传黑名单
			转载自:https://www.leavesongs.com/PENETRATION/apache-cve-2017-15715-vulnerability.html 目标环境: 比如,目标存在一个上 ... 
- python实战===用python识别图片中的中文
			需要安装的模块 PIL pytesseract 需要下载的工具: http://download.csdn.net/download/bo_mask/10196285 因为之前百度云的链接总失效,所以 ... 
