4539: [Hnoi2016]树

链接

分析:

  主席树+倍增。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define pa pair<int,int>
using namespace std;
typedef long long LL;
#define int LL
inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
struct Edge { int to, nxt; } e[N << ];
struct OPT { int l, r, fa, rt; } q[N];
int head[N], dfn[N], st[N], ed[N], pos[N], fa[N][], siz[N], f[N][], g[N][], d1[N], d2[N];
set< pa > s;
int En, Index, NowIndex, n; inline void add_edge(int u,int v) {
++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
++En; e[En].to = u, e[En].nxt = head[v]; head[v] = En;
}
struct SegmentTree{
int sum[N * ], ls[N * ], rs[N * ], Root[N], TreeIndex;
void Insert(int l,int r,int &now,int pre,int p) {
if (!now) now = ++TreeIndex;
sum[now] = sum[pre] + ;
if (l == r) return ;
int mid = (l + r) >> ;
if (p <= mid) {
rs[now] = rs[pre];
Insert(l, mid, ls[now], ls[pre], p);
} else {
ls[now] = ls[pre];
Insert(mid + , r, rs[now], rs[pre], p);
}
}
int query(int l,int r,int H,int T,int k) {
if (l == r) return l;
int mid = (l + r) >> ;
if (k <= sum[ls[T]] - sum[ls[H]]) return query(l, mid, ls[H], ls[T], k);
else return query(mid + , r, rs[H], rs[T], k - (sum[ls[T]] - sum[ls[H]]));
}
}T;
void dfs(int u) {
d1[u] = d1[fa[u][]] + ;
st[u] = ++Index; pos[Index] = u; siz[u] = ;
for (int i = ; i <= ; ++i) fa[u][i] = fa[fa[u][i - ]][i - ];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v == fa[u][]) continue;
fa[v][] = u;
dfs(v);
siz[u] += siz[v];
}
ed[u] = Index;
}
int LCA1(int u,int v) {
if (d1[u] < d1[v]) swap(u, v);
int d = d1[u] - d1[v];
for (int i = ; ~i; --i) if ((d >> i) & ) u = fa[u][i];
if (u == v) return u;
for (int i = ; ~i; --i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][];
}
int getdis(int x,int y) {
return d1[x] + d1[y] - d1[LCA1(x, y)] * ;
}
void add(int id) {
int x = read(), y = read(), z;
q[id].l = NowIndex, q[id].r = (NowIndex += siz[x]) - , q[id].rt = x;
set< pa > :: iterator it = s.lower_bound(pa(y, )); z = q[it->second].rt;
q[id].fa = T.query(, n, T.Root[st[z] - ], T.Root[ed[z]], y - q[it->second].l + );
f[id][] = it->second, g[id][] = getdis(q[id].fa, z) + ;
d2[id] = d2[it->second] + ;
for (int i = ; i <= ; ++i) f[id][i] = f[f[id][i - ]][i - ], g[id][i] = g[id][i - ] + g[f[id][i - ]][i - ];
s.insert(pa(q[id].r, id));
}
int LCA2(int u,int v,int tu,int tv) {
if (d2[u] < d2[v]) swap(u, v), swap(tu, tv);
int ans = , t = u, d = d2[u] - d2[v];
for (int i = ; ~i; --i) if ((d >> i) & ) ans += g[u][i], u = f[u][i];
if (u == v) {
d --; ans = ; u = t;
for (int i = ; ~i; --i) if ((d >> i) & ) ans += g[t][i], t = f[t][i];
ans += getdis(q[t].fa, tv) + + getdis(tu, q[u].rt);
return ans;
}
ans += getdis(tu, q[t].rt) + getdis(tv, q[v].rt);
for (int i = ; ~i; --i) if (f[u][i] != f[v][i]) ans += g[u][i] + g[v][i], u = f[u][i], v = f[v][i];
ans += getdis(q[u].fa, q[v].fa) + ;
return ans;
}
void Ask() {
int u = read(), v = read(), ans, iu, iv, tu, tv;
iu = s.lower_bound(pa(u, ))->second, iv = s.lower_bound(pa(v, ))->second;
tu = T.query(, n, T.Root[st[q[iu].rt] - ], T.Root[ed[q[iu].rt]], u - q[iu].l + );
tv = T.query(, n, T.Root[st[q[iv].rt] - ], T.Root[ed[q[iv].rt]], v - q[iv].l + );
if (iu != iv) ans = LCA2(iu, iv, tu, tv);
else ans = getdis(tu, tv);
printf("%lld\n", ans);
}
signed main() {
n = read();int m = read(), Q = read();
for (int i = ; i < n; ++i) add_edge(read(), read());
dfs();
for (int i = ; i <= n; ++i)
T.Insert(, n, T.Root[i], T.Root[i - ], pos[i]);
NowIndex = n + ;
s.insert(pa(n, )); q[].l = , q[].r = n, q[].rt = , q[].fa = ;
for (int i = ; i <= m; ++i) add(i + );
while (Q --) Ask();
return ;
}

4539: [Hnoi2016]树的更多相关文章

  1. BZOJ 4539: [Hnoi2016]树 [主席树 lca]

    4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...

  2. bzoj 4539 [Hnoi2016]树——主席树+倍增

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4539 明明就是把每次复制的一个子树当作一个点,这样能连出一个树的结构,自己竟然都没想到.思维 ...

  3. bzoj 4539: [Hnoi2016]树

    Description 小A想做一棵很大的树,但是他手上的材料有限,只好用点小技巧了.开始,小A只有一棵结点数为N的树,结 点的编号为1,2,-,N,其中结点1为根:我们称这颗树为模板树.小A决定通过 ...

  4. [BZOJ4539][HNOI2016]树(主席树)

    4539: [Hnoi2016]树 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 746  Solved: 292[Submit][Status][D ...

  5. 【LG3248】[HNOI2016]树

    [LG3248][HNOI2016]树 题面 洛谷 题解 因为每次你加入的点是原树上某一棵子树 那么我们一次加入一个点,代表一棵子树加到大树下面 那么我们要找到一个点在一个大点中用主席树在\(dfs\ ...

  6. [HNOI2016]树(可持久化线段树+树上倍增)

    [HNOI2016]树(可持久化线段树+树上倍增) 题面 给出一棵n个点的模板树和大树,根为1,初始的时候大树和模板树相同.接下来操作m次,每次从模板树里取出一棵子树,把它作为新树里节点y的儿子.操作 ...

  7. BZOJ4539: [Hnoi2016]树

    复制的树缩点,主席树查k小,毫无技术含量,纯码农题. #include<bits/stdc++.h> #define u first #define v second #define F ...

  8. [HNOI2016]树

    Description 小A想做一棵很大的树,但是他手上的材料有限,只好用点小技巧了.开始,小A只有一棵结点数为N的树,结 点的编号为1,2,…,N,其中结点1为根:我们称这颗树为模板树.小A决定通过 ...

  9. 2019.03.25 bzoj4539: [Hnoi2016]树(主席树+倍增)

    传送门 题意:给一棵大树,令一棵模板树与这棵树相同,然后进行mmm次操作,每次选择模板树中的一个节点aaa和大树中一个节点bbb,把aaa这棵子树接在bbb上面,节点编号顺序跟aaa中的编号顺序相同. ...

随机推荐

  1. 用华为eNSP模拟器配置Hybrid、Trunk和Access三种链路类型端口

    上一篇文章写到三层交换机实现多个VLAN之间互相通讯,有朋友提问要如何进行配置,可有案例分析.其实那天我在写的时候也有做过模拟,只是后来没有保存.今天重新模拟一次,并附上详细配置命令,希望能够帮助到大 ...

  2. 初始Flask

    一.Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架 Flask是一个基于P ...

  3. Linux学习---Linux用户审计简单版

    [root@localhost root]# vim /etc/profile # SHENJI history USER=`whoami` USER_IP=`who -u am i 2>/de ...

  4. jQuery实现简易轮播图的效果

    (图片素材取自于小米官网) 刚开始接触jQuery的学习,个人觉得如果为了实现多数的动态效果,jQuery的确很简易方便. 下面简易的轮播图效果,还请前辈多多指教~ (努力学习react vue an ...

  5. Uva514

    https://vjudge.net/problem/UVA-514 #include <bits/stdc++.h> using namespace std; ; int target[ ...

  6. python redis 的基本操作指令

    #!/usr/bin/env python # -*- coding: utf-8 -*- ''' redis基本命令和基本用法详解 1.redis连接 2.redis连接池 3.redis基本命令 ...

  7. C语言程序设计I—第九周教学

    第九周教学总结(28/10-03/11) 教学内容 第三章 分支结构 3.3 查询自动售货机中商品的价格 课前准备 在蓝墨云班课发布资源: PTA:2018秋第九周作业1 3.3 分享码:530571 ...

  8. ZOJ 2475 Benny's Compiler(dfs判断有向图给定点有没有参与构成环)

    B - Benny's Compiler Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu ...

  9. POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120 ...

  10. Windows App开发之应用布局与基本导航

    简单演示样例看页面布局和导航 首先依照上一篇博客中的顺序来新建一个项目.新建好之后就点开MainPage.xaml開始写程序了. <Grid Background="{ThemeRes ...