树上差分

这应该是一道很简单的树上差分了。。就是问每个点被覆盖了多少次。

要注意我们最后dfs后,要把除第一个节点以外的所有点的-1,因为有些点作为起点和终点覆盖了两次,按照题目意思是不用覆盖两次的。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
}
const int N = 300005;
int n, s[N], cnt, head[N], depth[N], p[N][20], t, val[N];
bool vis[N];
struct Edge { int v, next; }edge[N<<1]; void addEdge(int a, int b){
edge[cnt].v = b, edge[cnt].next = head[a], head[a] = cnt ++;
} void dfs(int s, int fa){
depth[s] = depth[fa] + 1;
p[s][0] = fa;
for(int i = 1; i <= t; i ++){
p[s][i] = p[p[s][i - 1]][i - 1];
}
for(int i = head[s]; i != -1; i = edge[i].next){
int u = edge[i].v;
if(u == fa) continue;
dfs(u, s);
}
} int lca(int x, int y){
if(depth[x] < depth[y]) swap(x, y);
for(int i = t; i >= 0; i --){
if(depth[p[x][i]] >= depth[y]) x = p[x][i];
}
if(x == y) return y;
for(int i = t; i >= 0; i --){
if(p[x][i] != p[y][i]) x = p[x][i], y = p[y][i];
}
return p[y][0];
} void dfs(int s){
vis[s] = true;
for(int i = head[s]; i != -1; i = edge[i].next){
int u = edge[i].v;
if(vis[u]) continue;
dfs(u);
val[s] += val[u];
}
} int main(){ full(head, -1);
n = read();
for(int i = 0; i < n; i ++) s[i] = read();
for(int i = 0; i < n - 1; i ++){
int u = read(), v = read();
addEdge(u, v), addEdge(v, u);
}
t = (int)(log(n) / log(2)) + 1;
dfs(s[0], 0);
for(int i = 0; i < n - 1; i ++){
val[s[i]] ++, val[s[i + 1]] ++;
int f = lca(s[i], s[i + 1]);
val[f] --, val[p[f][0]] --;
}
dfs(s[0]);
for(int i = 1; i < n; i ++) val[s[i]] --;
for(int i = 1; i <= n; i ++) printf("%d\n", val[i]);
return 0;
}

洛谷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松鼠的新家

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

  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. Spring如何加载log4j配置文件

    今天有朋友在群里问了这个问题,于是写了这篇文章进行整理. 问题如下: 在项目中添加了log4j.properties配置文件,并没有在Spring配置文件中配置,也没有在web.xml中配置,但是代码 ...

  2. DSL 系列(2) - 插件的论述与实现

    前言 本文主要探讨基于 DSL(domain specific language) 之上的插件设计,他们是领域的附属,为领域提供额外的服务,但领域不依赖于他们. 1. 论述 领域应当尽可能地去专注他的 ...

  3. C#里面滥用String造成的性能问题

    前两天给我们的json写一个解析函数, 之前用的正宗的json parser, 支持完整的json特性. 但是实际上我们用到特性, 只有key-value的映射, value的类型只有数字和字符串两种 ...

  4. Web测试和App测试有什么区别

    WEB测试和App测试从流程上来说,没有区别.都需要经历测试计划方案,用例设计,测试执行,缺陷管理,测试报告等相关活动.从技术上来说,WEB测试和APP测试其测试类型也基本相似,都需要进行功能测试.性 ...

  5. 机器学习第一篇——最近邻kNN

    机器学习监督学习中,根据解决问题的连续性和离散型,分为分类问题和回归问题.最邻近算法kNN是一种最为直接和简便的分类方法. kNN本质上,是计算目标到模型的欧式距离,从而判定目标所属的类别. 首先,在 ...

  6. 【学习总结】GirlsInAI ML-diary day-16-pip install XX

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day16 Pip pip是python 著名的包管理工具,在python开发过程必不可少. 本节带大家了解用pip实现的p ...

  7. 实验楼----PHP大法

    地址:http://www.shiyanbar.com/ctf/2008 题目:http://ctf5.shiyanbar.com/DUTCTF/index.php

  8. PHP中stdClass的意义

    在WordPress中很多地方使用stdClass来定义一个对象(而通常是用数组的方式),然后使用get_object_vars来把定义的对象『转换』成数组. 如下代码所示:   1 2 3 4 5 ...

  9. 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序

    题目: 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序 public static int maxGap(int nums[]) { if ( ...

  10. 用户认证--------------auth模块

    一.auth模块 from django.contrib import auth 1 .authenticate()   :验证用户输入的用户名和密码是否相同 提供了用户认证,即验证用户名以及密码是否 ...