题目链接:https://www.luogu.org/problemnew/show/P3258

谁说树剖过不去会RE呢?

我今天就是要强行树剖了

树剖强艹

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn = 500010;
ll ans[maxn], son[maxn], deep[maxn], size[maxn], fa[maxn], top[maxn], seg[maxn], num, n, m, path[maxn];
struct edge{
ll to, next;
}e[maxn<<2];
ll head[maxn], cnt;
void add(ll u, ll v)
{
e[++cnt].to = v; e[cnt].next = head[u]; head[u] = cnt;
e[++cnt].to = u; e[cnt].next = head[v]; head[v] = cnt;
}
class Segment_Tree{
public:
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
ll tree[maxn<<2], lazy[maxn<<2];
void build(ll l, ll r, ll rt)
{
if(l == r)
{
tree[rt] = 0;
return;
}
ll mid = (l + r) >> 1;
build(lson);
build(rson);
PushUP(rt);
}
void update(ll left, ll right, ll add, ll l, ll r, ll rt)
{
if(left <= l && right >= r)
{
lazy[rt] += add;
tree[rt] += (r - l + 1) * add;
return;
}
ll mid = (l + r) >> 1;
PushDOWN(l, r, rt);
if(left <= mid) update(left, right, add, lson);
if(right > mid) update(left, right, add, rson);
PushUP(rt);
}
ll query(ll left, ll right, ll l, ll r, ll rt)
{
ll res = 0;
if(left <= l && right >= r)
{
return tree[rt];
}
ll mid = (l + r) >> 1;
PushDOWN(l, r, rt);
if(left <= mid) res += query(left, right, lson);
if(right > mid) res += query(left, right, rson);
return res;
}
private:
void PushUP(ll rt)
{
tree[rt] = tree[rt<<1] + tree[rt<<1|1];
}
void PushDOWN(ll l, ll r, ll rt)
{
ll mid = (l + r) >> 1;
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
tree[rt<<1] += (mid-l+1)*lazy[rt];
tree[rt<<1|1] += (r-mid)*lazy[rt];
lazy[rt] = 0;
}
}
}T;
void dfs1(ll u, ll f, ll d)
{
ll maxson = -1;
size[u] = 1;
deep[u] = d;
fa[u] = f;
for(ll i = head[u]; i != -1; i = e[i].next)
{
ll v = e[i].to;
if(f != v)
{
dfs1(v, u, d+1);
size[u] += size[v];
if(size[v] > maxson) son[u] = v, maxson = size[v];
}
}
}
void dfs2(ll u, ll t)
{
seg[u] = ++num;
top[u] = t;
if(!son[u]) return;
dfs2(son[u], t);
for(ll i = head[u]; i != -1; i = e[i].next)
{
ll v = e[i].to;
if(v == son[u] || v == fa[u]) continue;
dfs2(v, v);
}
}
ll LCA(ll x, ll y)
{
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return deep[x] < deep[y] ? x : y;
}
ll Qson(ll x)
{
ll res = 0;
res += T.query(seg[x], seg[x]+size[x]-1, 1, n, 1);
return res;
}
void Updson(ll x, ll y)
{
T.update(seg[x], seg[x]+size[x]-1, y, 1, n, 1);
}
ll Qrange(ll x, ll y)
{
ll res = 0;
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x, y);
res += T.query(seg[top[x]], seg[x], 1, n, 1);
x = fa[top[x]];
}
if(deep[x] < deep[y]) swap(x, y);
res += T.query(seg[y], seg[x], 1, n, 1);
return res;
}
void Updrange(ll x, ll y, ll z)
{
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x, y);
T.update(seg[top[x]], seg[x], z, 1, n, 1);
x = fa[top[x]];
}
if(deep[x] < deep[y]) swap(x, y);
T.update(seg[y], seg[x], z, 1, n, 1);
}
int main()
{
memset(head, -1, sizeof(head));
scanf("%lld%lld",&n,&path[1]);
for(ll i = 2; i <= n; i++)
{
scanf("%lld",&path[i]);
ans[path[i]]--;
}
for(ll i = 1; i <= n-1; i++)
{
ll u, v;
scanf("%lld%lld",&u,&v);
add(u, v);
}
dfs1(1, 0, 1); dfs2(1, 1);
T.build(1, n, 1);
for(ll i = 2; i <= n; i++)
{
Updrange(path[i], path[i-1], 1);
}
for(ll i = 1; i <= n; i++) ans[i] += Qrange(i, i);
for(ll i = 1; i <= n; i++)
{
printf("%lld\n",ans[i]);
}
return 0;
}

【luogu P3258 [JLOI2014]松鼠的新家】 题解的更多相关文章

  1. 洛谷 P3258 [JLOI2014]松鼠的新家 题解

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  2. [Luogu] P3258 [JLOI2014]松鼠的新家

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...

  3. P3258 [JLOI2014]松鼠的新家题解

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(n\)个房间,并且有\(n-1\)根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树& ...

  4. P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...

  5. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  6. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

    [题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...

  7. [Luogu 3258] JLOI2014 松鼠的新家

    [Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...

  8. 洛谷P3258 [JLOI2014]松鼠的新家

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  9. P3258[JLOI2014]松鼠的新家(LCA 树上差分)

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

随机推荐

  1. hdu 3415 Max Sum of Max-K-sub-sequence 单调队列。

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  2. CentOS6下docker的安装和使用

    CentOS6下docker的安装和使用 Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS.Go语言.cgroup ...

  3. Install Java JDK JRE on Ubuntu/Debian with Apt-Get

    Introduction As a lot of articles and programs require to have Java installed, this article will gui ...

  4. How To Manage StartUp Applications In Ubuntu

    Ever felt the need to control startup applications in Ubuntu? You should, if you feel that your Ubun ...

  5. jquery 之节点操作

    一.添加节点 [添加内部子节点方法]:内部节点就是儿子节点 append()    在被选元素内部的结尾插入内容 appendTo()  将指定内容插入到被选标签内部的结尾 prepend()   在 ...

  6. ffmpeg 简介及使用

    简介 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url ...

  7. python 3 过滤股票

    参考某个博客,代码不全,地址找不到了见谅,加了些自己弄的算法. 备忘 #-*- coding: utf-8 -*-import os, reimport time def filefilter(com ...

  8. C# 平台问题

    最近在C#项目中嵌入一个视频软件Ffplayer,出现报错现象,提示平台开发视频.dll文件的兼容性和加载格式不正确的问题.最终查看是由于项目平台选择的是Any CPU和X86的引起的.目标平台有什么 ...

  9. [翻译] MMMaterialDesignSpinner

    MMMaterialDesignSpinner Usage To run the example project, clone the repo, and run pod install from t ...

  10. Linux入门-9 软件管理基础(CentOS)

    0. 源代码形式 1. RPM软件包管理 RPM RPM查询 RPM验证 2. YUM软件管理 YUM基本命令 YUM查询 创建YUM仓库 0. 源代码形式 绝大多数开源软件都是直接以源代码形式发布 ...