4539: [Hnoi2016]树
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]树的更多相关文章
- BZOJ 4539: [Hnoi2016]树 [主席树 lca]
4539: [Hnoi2016]树 题意:不想写.复制模板树的子树,查询两点间距离. *** 终于有一道会做的题了...... 画一画发现可以把每次复制的子树看成一个大点来建一棵树,两点的lca一定在 ...
- bzoj 4539 [Hnoi2016]树——主席树+倍增
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4539 明明就是把每次复制的一个子树当作一个点,这样能连出一个树的结构,自己竟然都没想到.思维 ...
- bzoj 4539: [Hnoi2016]树
Description 小A想做一棵很大的树,但是他手上的材料有限,只好用点小技巧了.开始,小A只有一棵结点数为N的树,结 点的编号为1,2,-,N,其中结点1为根:我们称这颗树为模板树.小A决定通过 ...
- [BZOJ4539][HNOI2016]树(主席树)
4539: [Hnoi2016]树 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 746 Solved: 292[Submit][Status][D ...
- 【LG3248】[HNOI2016]树
[LG3248][HNOI2016]树 题面 洛谷 题解 因为每次你加入的点是原树上某一棵子树 那么我们一次加入一个点,代表一棵子树加到大树下面 那么我们要找到一个点在一个大点中用主席树在\(dfs\ ...
- [HNOI2016]树(可持久化线段树+树上倍增)
[HNOI2016]树(可持久化线段树+树上倍增) 题面 给出一棵n个点的模板树和大树,根为1,初始的时候大树和模板树相同.接下来操作m次,每次从模板树里取出一棵子树,把它作为新树里节点y的儿子.操作 ...
- BZOJ4539: [Hnoi2016]树
复制的树缩点,主席树查k小,毫无技术含量,纯码农题. #include<bits/stdc++.h> #define u first #define v second #define F ...
- [HNOI2016]树
Description 小A想做一棵很大的树,但是他手上的材料有限,只好用点小技巧了.开始,小A只有一棵结点数为N的树,结 点的编号为1,2,…,N,其中结点1为根:我们称这颗树为模板树.小A决定通过 ...
- 2019.03.25 bzoj4539: [Hnoi2016]树(主席树+倍增)
传送门 题意:给一棵大树,令一棵模板树与这棵树相同,然后进行mmm次操作,每次选择模板树中的一个节点aaa和大树中一个节点bbb,把aaa这棵子树接在bbb上面,节点编号顺序跟aaa中的编号顺序相同. ...
随机推荐
- The operation names in the portType match the method names in the SEI or Web service implementation class.
The Endpoint validation failed to validate due to the following errors: :: Invalid Endpoint Interfac ...
- 去除Xcode6创建工程时自带的storyboard
去除Xcode6创建工程时自带的storyboard 1. 删除storyboard文件,并在setting里面清空加载storyboard: 2. 导入ViewController到appDeleg ...
- word用宏命令完美解决列表编号变黑块的问题
相信很多人跟我一样,多次定义新的多级列表,会导致列表编号变成下面这样黑块 在百度搜索结果尝试了鼠标左键选中应用样式,文档关闭后打开问题依旧: 还是得感谢万能的Google,帮我找到了答案. 问题根因: ...
- fun()可拆分赋值 fun()可以拆, 变成 fun 和 括号, fun 可以赋值
2. 函数名可以赋值给其他变量 ---> 就是 func()可以拆 def fun (): print("哈哈") a = fun # 拆分 fun()的 fu ...
- redis 配置文件redis.conf
daemonize yes #---默认值no,该参数用于定制redis服务是否以守护模式运行.--- pidfile /var/run/redis.pid #默认值/var/run/redis.pi ...
- hihocoder Round #c1(hihoCoder太阁最新面经算法竞赛1 )
Test链接:https://cn.vjudge.net/contest/231849 选自hihoCoder太阁最新面经算法竞赛1 更多Test:传送门 A:区间求差 给一组区间集合A和区间集合B, ...
- @objc vs @objc dynamic官方解释
Some Objective-C APIs—like target-action—accept method or property names as parameters, then use tho ...
- zookeeper 快速入门
分布式系统简介 在分布式系统中另一个需要解决的重要问题就是数据的复制.我们日常开发中,很多人会碰到一个问题:客户端C1更新了一个值K1由V1更新到V2.但是客户端C2无法立即读取到K的最新值.上面的例 ...
- POJ Football Game 【NIMK博弈 && Bash 博弈】
Football Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 451 Accepted: 178 Descr ...
- [luogu2668] 斗地主
题面 这好像就是道**暴搜题, 由于可以回溯, 所以顺序其实没有多大的关系, 见代码吧... 具体代码 #include <iostream> #include <cstring ...