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. 关于Vue中:key="index"的console警告

    在写vue项目时,浏览器的console出现如下警告信息: [Vue warn]: Property or method "index" is not defined on the ...

  2. Vue的路由

    Vue可以实现一种类是ajax不刷新但是切换界面 然后 只是在你的url中的当前地址后面追加信息 首先你要先当如这个路由的模块: <script src="https://unpkg. ...

  3. Linux blkid命令详解

    blkid命令对查询设备上所采用文件系统类型进行查询.blkid主要用来对系统的块设备(包括交换分区)所使用的文件系统类型.LABEL.UUID等信息进行查询.要使用这个命令必须安装e2fsprogs ...

  4. Sharepoint 2013 多服务器域的目录服务器和搜索服务的配置

    一般而言,大部分的sharepoint的管理工作均可以通过Centrlal Admin完成,可惜这个操作不得不要用powershell. 假如Webfront服务器叫 WebServer 目录服务器叫 ...

  5. 只要下面看到func() 带括号的,就会弹上去找对应的函数,然后执行相应的函数块

    def func1(): print("呵呵")def func2(): print("呵呵")def func3(): print("呵呵" ...

  6. windows下python 正确安装词云包wordcloud的方法

    安装wordcloud的时候果然还是出现了问题,试了网上说的好多办法,最后找到了一种成功率高的,可以优先尝试一下 下载.whl文件http://www.lfd.uci.edu/~gohlke/pyth ...

  7. postGresql关键字字段重名

    在postGresql中如果关键字和自定义的字段重名 即使使用[  ](中括号)或者 ' '(单引号)都没有用,经本人实验. 如果使用" "(双引号),则可以.

  8. linux块设备缓存bcache

    1 Bcache介绍Bcache是一种缓存技术,它是根据SSD的特性设计的,由于SSD的随机读写速度要比普通硬盘的随机读写快N多倍,但是一般SSD的容量小且贵,当然土豪除外,所以我们可以综合SSD的读 ...

  9. 代码覆盖率测试及 GitHub 自动化集成

    本文对应项目为 learn-coverage-test,可以对照项目案例进行阅读. 覆盖率测试 在写代码的时候,我们有时候会进行代码测试以保证我们代码的可执行性.但是测试代码只能保证测试案例能够通过, ...

  10. Golang context包解读

    Context 通常被译作 上下文 ,一般理解为程序单元的一个运行状态.现场.快照,而翻译中 上下 又很好地诠释了其本质,上下上下则是存在上下层的传递, 上 会把内容传递给 下 . 在Go语言中,程序 ...