[Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 2350 Solved: 1212
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
HINT
2<= n <=300000
分析:
今天做了noip2015 day2 t3,发现这道省选题竟然是它的简化版。。。。。。。。
道理一样求树上前缀和,以第一个访问的为根,求出dfs序(每个点的st和en)和lca。
对于每一个访问的点u,和前一个点pre在前缀和数组里 +1,他们的lca -2.
这样对于除了根节点以外的所有点,他们的起始位置到结尾位置的和就为那条边经过的次数。(这个用前缀和O(n)处理,每次求一个点只用sum[en] - sum[st - 1]就可以了)。
对于每条边出现次数x,两端的点答案各加x/2,如果为奇数深度更深的那个点答案再加1
根节点最后要加一,最后位置要减1,其实比noip那道题还简单。。。。。
AC代码:
# include <iostream>
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <algorithm>
using namespace std;
const int N = 3e5 + ;
int head[N],cnt,n,lg,maxn;
int fa[N][],dep[N],vis[N];
struct Edge{
int to,next;
}edge[N << ];
void AddEdge(int u,int v){
Edge E = {v,head[u]};
edge[++cnt] = E;head[u] = cnt;
}
int st[N],en[N];
long long ans[N],sum[N];
void dfs(int u,int pre){
st[u] = ++cnt;
for(int i = head[u];i;i = edge[i].next){
int v = edge[i].to;
if(v == pre)continue;
fa[v][] = u;
dep[v] = dep[u] + ;
dfs(v,u);
}
maxn = max(maxn,dep[u]);
en[u] = cnt;
}
int lca(int x,int y){
if(dep[x] < dep[y])swap(x,y);
for(int i = lg;i >= ;i--){
if(dep[x] - ( << i) >= dep[y])x = fa[x][i];
}
for(int i = lg;i >= ;i--){
if((dep[x] - ( << i)) && fa[x][i] != fa[y][i]){
x = fa[x][i];
y = fa[y][i];
}
}
if(x != y)x = fa[x][];
return x;
}
int main(){
scanf("%d",&n);
int x,y,root;
for(int i = ;i <= n;i++){
scanf("%d",&vis[i]);
}
root = vis[];
for(int i = ;i < n;i++){
scanf("%d %d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
cnt = ;
dep[root] = maxn = ;
dfs(root,-);
int pre = root;
for(lg = ;( << lg) <= maxn;lg++);lg--;
for(int j = ;j <= lg;j++){
for(int i = ;i <= n;i++){
fa[i][j] = fa[fa[i][j - ]][j - ];
}
}
for(int i = ;i <= n;i++){
sum[st[vis[i]]]++;sum[st[pre]]++;
sum[st[lca(vis[i],pre)]] -= ;
pre = vis[i];
}
for(int i = ;i <= n;i++){
sum[i] += sum[i - ];
}
long long z;
for(int i = ;i <= n;i++){
z = sum[en[i]] - sum[st[i] - ];
if(z & 1LL){
ans[i]++;
}
ans[i] += z / 2LL;ans[fa[i][]] += z / 2LL;
}
ans[pre]--;ans[root]++;
for(int i = ;i <= n;i++){
printf("%lld\n",ans[i]);
}
}
[Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)的更多相关文章
- bzoj3631 [JLOI2014]松鼠的新家——树上差分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 树上差分:注意路径的结尾被多算了一次,最后要减去(不能提前减). 代码如下: #inc ...
- BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】
题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- bzoj3631: [JLOI2014]松鼠的新家(树上差分)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 题目大意:给定含有n个顶点的树,给定走遍整棵树顺序的序列a[1],a[2],a[3 ...
- bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)
题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...
- BZOJ3631: [JLOI2014]松鼠的新家
传送门 树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题. //BZOJ 3631 //by Cydiater //2016.10.25 #include <iost ...
- bzoj3631[JLOI2014 松鼠的新家 倍增lca+差分
裸的树上差分+倍增lca 每次从起点到终点左闭右开,这就有一个小技巧,要找到右端点向左端点走的第一步,然后差分就好了 #include<cstdio> #include<cstrin ...
- [JLOI2014]松鼠的新家 树上差分
差分 一开始竟然想分情况讨论来差分,然后发现各自情况要分析, 就是为了解决中间节点重复计算的问题, 结果 最后一想,中间重复计算了一次,那我最后减掉不就好了么,,, 那这就是一道差分裸题了(这是唯一不 ...
随机推荐
- VBA 从sql存储过程-记录集-导入
cnn.Open cnnstr cmd.ActiveConnection = cnn cmd.CommandTimeout = 120 cmd.CommandText = "dbo.t_bi ...
- QTableWidget表头样式
转载请注明出处:http://www.cnblogs.com/dachen408/p/7742680.html QTableView { background-color: rgba(255, 255 ...
- java生成饼图svg
package com.tellhow.svg; import java.io.File;import java.io.FileOutputStream; /** * * @author 风絮NO. ...
- mysql 表锁死的问题
select * from information_schema.innodb_trx; kill 34863;kill 34856;kill 34860;kill 34859;kill 34845; ...
- ES6(vue)对象词法扩展
ES6 允许声明在对象字面量时使用简写语法,来初始化属性变量和函数的定义方法,并且允许在对象属性中进行计算操作: function getCar(make, model, value) { retur ...
- jsp公共头信息的抽取(相对路径的修改)
1,抽取出的公共头信息 <%@ page language="java" contentType="text/html; charset=UTF-8" p ...
- NETCORE使用DB First
1)引用 (1)Install-Package Microsoft.EntityFrameworkCore (2)Install-Package Microsoft.EntityFrameworkCo ...
- vmware linux虚拟机与本地物理机共享文件夹
cd /mnt/hgfs 使用Vmware安装了linux虚拟机后,开发时,为了方便文件的传输等,因此需要使用共享文件夹,减少工作量.共享文件夹需要用到vmware提供的vmware tools工具, ...
- 什么是JavaScript框架-------share
摘要:现代网站和web应用程序趋向于依赖客户端的大量的javascript来提供丰富的交互.特别是通过不刷新页面的异步请求来返回数据或从服务器端的脚本(或数据系统)中得到响应.在这篇文章中,你将会了解 ...
- poj-1163 动态规划
这道题目并不能直接使用递归,因为 7(1) 7(1) 7(1) 7(1) 7(2) 7(1) 7(1) 7(3) 7(3) ...