【洛谷P3258】松鼠的新家
很好的一道题
LCA+树上前缀和
sum数组是前缀和数组,
分类讨论一下,
1.访问到一个点p1,若下一个点p2需要往儿子下面找的话,那么lca就是这个点p1,则sum[p1]--; sum[p2]++;
2.访问到一个点p1,若下一个点p2需要往父亲上找的话,那么lca就是p2,则sum[f[p2][0]]--; sum[f[p1][0]]++
3.访问到一个点p1,若下一个点p2需要跨过p1,p2的lca的话,则sum[lca]--; sum[f[lca][0]]--; sum[p1]++; sum[p2]++;
需要注意的就是判重(有些地方会重复加)
#include<cstdio>
#include<cstring>
using namespace std;
const int N=,p=;
int n,size,head[N<<],a[N];
int nxt[N<<],to[N<<];
int father[N][p+],sum[N],cnt[N],deep[N];
void swap(int &a,int &b){
int tmp=a;
a=b;
b=tmp;
}
void uni(int x,int y){
size++;
nxt[size]=head[x];
head[x]=size;
to[size]=y;
}
void dfs(int fa,int x){
for (int k=head[x];k;k=nxt[k]){
int y=to[k];
if (y==fa)
continue;
deep[y]=deep[x]+;
father[y][]=x;
dfs(x,y);
}
}
void pre(){
for (int j=;j<=p;j++)
for (int i=;i<=n;i++)
father[i][j]=father[father[i][j-]][j-];
}
int LCA(int x,int y){
if (deep[x]<deep[y])
swap(x,y);
int d=deep[x]-deep[y];
for (int j=p;j>=;j--)
if (d&(<<j))
x=father[x][j];
if (x==y)
return x;
for (int j=p;j>=;j--)
if (father[x][j]!=father[y][j]){
x=father[x][j];
y=father[y][j];
}
return father[x][];
}
void Dfs(int fa,int x){
if (!nxt[head[x]]&&x!=){
cnt[x]=sum[x];
return;
}
for (int k=head[x];k;k=nxt[k]){
int y=to[k];
if (fa==y)
continue;
Dfs(x,y);
cnt[x]+=cnt[y];
}
cnt[x]+=sum[x];
}
int main(){
int x,y;
size=;
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&a[i]);
for (int i=;i<n;i++){
scanf("%d %d",&x,&y);
uni(x,y);
uni(y,x);
}
deep[]=;
dfs(,);
pre();
int lca=LCA(a[],a[]);
sum[a[]]++;
sum[a[]]++;
sum[lca]--;
sum[father[lca][]]--;
for (int i=;i<n;i++){
x=a[i];
y=a[i+];
int lca=LCA(x,y);
if (x==lca){//down
sum[x]--;
sum[y]++;
}
else if (y==lca){//up
sum[father[y][]]--;
sum[father[x][]]++;
}
else{
sum[y]++;
sum[father[x][]]++;
sum[lca]--;
sum[father[lca][]]--;
}
}
Dfs(,);
cnt[a[n]]--;
for (int i=;i<=n;i++)
printf("%d\n",cnt[i]);
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松鼠的新家
题目传送门 恩,很明显的一个树剖题,配合树上差分其实也并不难,不过无奈蒟蒻树剖还没那么熟练,而且树上差分也做的少,所以这题愣是做了一中午......唉,果然我还是太菜了.恩,具体做法在代码中解释吧: ...
- 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根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
随机推荐
- set JAVA_HOME in RHEL/CentOS
3.3. Install OpenJDK on Red Hat Enterprise Linux Introduction OpenJDK is one of many Java Developmen ...
- Functional testing - python, selenium and django
Functional testing - python selenium django - Source Code : from selenium import webdriverfrom sele ...
- google快捷键,通过浏览器本身来查看
今天玩google浏览器时发现一个不需要访问google就能查看其快捷键的方式,再此记录一下,以备后用. 1:打开Google浏览器 2:打开开发者工具,有三种方法 2-1:按F12快捷键 2-2:按 ...
- String 及其数组的相关问题
由其他类型转String一般用三种方法 方法1:采用 Object.toString()方法 请看下面的例子: Object object = getObject(); System.out.prin ...
- C# 读取Excel内容
一.方法 1.OleD方法实现该功能. 2.本次随笔内容只包含读取Excel内容,并另存为. 二.代码 (1)找到文档代码 OpenFileDialog openFile = new OpenFile ...
- sublime text3 输入中文的解决方法及注册
让它输入中文的原理就是给sublime text3给打上个补丁libsublime-imfix.so,这个补丁可以直接git回来,或者下载补丁的源码编译安装. Ubuntu可以直接按照下面的教程 su ...
- Asp.net using Oracle.DataAccess.dll access oracle 11g 64bit & x86
使用.net访问oracle数据库时一般需要在机器上安装instantclient才能正常连接. 下面介绍一种不用安装instantclient直接引用dll就用.net能连接oracle数据库的方法 ...
- VC++中操作XML(MFC、SDK)转
[转]VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++ ...
- codevs 1163 访问艺术馆
1163 访问艺术馆 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 皮尔是一个出了名的盗画者,他经过数月的精心准备,打算到艺术馆盗画.艺术馆的结 ...
- .net 更新数据 ado.net parameter
UPDATE yborder_ordernotes SET recoder400= @FileAddress, havefile400 = 1 WHERE id = @OrderID Maticsof ...