[Luogu 3258] JLOI2014 松鼠的新家
[Luogu 3258] JLOI2014 松鼠的新家
LCA + 树上差分。
我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分。
qwq不讲了不讲了,贴代码。
#include <algorithm>
#include <cstdio>
#include <cstring>
#define nullptr NULL
const int MAXN = 300010;
int n, a[MAXN];
namespace HLD
{
int qwq[MAXN];
class Graph
{
private:
bool vis[MAXN];
int num;
struct Node
{
int depth, size, father, son, top, DFN;
}s[MAXN];
struct Edge
{
int to;
Edge *next;
Edge(int to, Edge* next): to(to), next(next){}
~Edge(void)
{
if(next!=nullptr)
delete next;
}
}*head[MAXN];
void Modify(int l, int r, int k)
{
qwq[s[l].DFN] += k;
qwq[s[r].DFN + 1] -= k;
}
void Add(int x, int y)
{
int a, b;
while((a = s[x].top) ^ (b = s[y].top))
if(s[a].depth > s[b].depth)
{
Modify(a, x, 1);
x = s[a].father;
}
else
{
Modify(b, y, 1);
y = s[b].father;
}
if(s[x].depth < s[y].depth)
Modify(x, y, 1);
else
Modify(y, x, 1);
}
public:
Graph(int n): num(0)
{
memset(vis, 0, sizeof vis);
memset(s, 0, sizeof s);
std :: fill(head + 1, head + n + 1, (Edge*)nullptr);
}
~Graph(void)
{
for(int i = 1; i <= n; ++i)
delete head[i];
}
void AddEdges(int u, int v)
{
head[u] = new Edge(v, head[u]);
head[v] = new Edge(u, head[v]);
}
void DFS1(int u, int k)
{
s[u].depth = k;
s[u].size = 1;
int v;
for(Edge* i = head[u]; i != nullptr; i = i -> next)
if(!s[v = i -> to].depth)
{
DFS1(v, k + 1);
s[v].father = u;
s[u].size += s[v].size;
if(s[v].size > s[s[u].son].size)
s[u].son = v;
}
}
void DFS2(int u, int top)
{
s[u].top = top;
s[u].DFN = ++num;
vis[u] = true;
if(s[u].son)
DFS2(s[u].son, top);
int v;
for(Edge* i = head[u]; i != nullptr; i = i -> next)
if(!vis[v = i -> to])
DFS2(v, v);
}
void Walk(int x, int y)
{
Add(x, y);
Modify(y, y, -1);
}
void Find(void)
{
for(int i = 1; i < n; ++i)
qwq[i + 1] += qwq[i];
for(int i = 1; i <= n; ++i)
printf("%d\n", qwq[s[i].DFN]);
}
}*G;
void Init(void)
{
G = new Graph(n);
for(int i = 1, u, v; i < n; ++i)
{
scanf("%d %d", &u, &v);
G -> AddEdges(u, v);
}
G -> DFS1(1, 1);
G -> DFS2(1, 1);
}
}
int main(void)
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
HLD :: Init();
for(int i = 1; i < n; ++i)
HLD :: G -> Walk(a[i], a[i + 1]);
HLD :: G -> Find();
return 0;
}
谢谢阅读。
[Luogu 3258] JLOI2014 松鼠的新家的更多相关文章
- [Luogu] P3258 [JLOI2014]松鼠的新家
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- 【luogu P3258 [JLOI2014]松鼠的新家】 题解
题目链接:https://www.luogu.org/problemnew/show/P3258 谁说树剖过不去会RE呢? 我今天就是要强行树剖了 树剖强艹 #include <cstdio&g ...
- [JLOI2014]松鼠的新家(树链剖分)
[JLOI2014]松鼠的新家(luogu) Description 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间 ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
- P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家
[题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
随机推荐
- Python库moviepy
目录 介绍和下载安装 视频截取和拼接 视频加水印
- synchronized、锁、多线程同步的原理是咋样
先综述个结论: 一般说的synchronized用来做多线程同步功能,其实synchronized只是提供多线程互斥,而对象的wait()和notify()方法才提供线程的同步功能. 一般说synch ...
- 由一个滑动条的任务需求产生一个对UISlider控件的探讨
任务需求样式:
- vue 中使用better-scroll 遇到的问题
以下是遇到问题以及解决方法 1.使用v-for 循环循环出来的列表,不能滚动. 原因是没有给wrapper 父层 加高度,当子层的高度大于父层的高度,才能滚动 打印scroll 对象,显示如此 竟然相 ...
- 关闭Centos5.5的写磁盘I/O功能
一个Linux文件默认有3个时间. atime:对此文件的访问时间. ctime:此文件inode发生变化的时间. mtime:此文件的修改时间. 如果有多个小文件(比如Web服务器的页面上有多个小图 ...
- 约跑APP测试
项目名:约跑APP 用户需求规格说明书URL:http://www.cnblogs.com/liquan/p/6071804.html 组长博客URL:http://www.cnblogs.com/l ...
- xshell 常用快捷键
1.连接mysql数据库mysql -uroot -p -h127.0.0.1 -P3306 2.列出所有sessionshow full processlist; 3.查看20条执行时间最长的SQL ...
- ubuntu下安装软件的三种方法
在ubuntu当中,安装应用程序常用的三种方法,分别是apt-get,dpkg安装deb和make install安装源码包三种. apt-get方法 使用apt-get install来安装应用程序 ...
- [学习]仿照cnblog 搭建 Oracle RAC 双节点 困.. 后续做不下去了..
1. 学习地址: https://blog.csdn.net/yuzifen?t=1 2. 克隆之前创建好的虚拟机: 3. 给虚拟机增加新的硬盘. 注意事项 1) 必须是厚置备的磁盘才可以. 2) 必 ...
- vue 组件 模板中根数据绑定需要指明路径并通信父
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>T ...