lca

ACM模板——LCA

寵の児 提交于 2019-11-30 12:05:16
1 #include <bits/stdc++.h> 2 #define _for(i,a,b) for(int i = (a);i < b;i ++) 3 #define _rep(i,a,b) for(int i = (a);i > b;i --) 4 #define INF 0x3f3f3f3f 5 #define pb push_back 6 #define maxn 500003 7 typedef long long ll; 8 using namespace std; 9 10 inline ll read() 11 { 12 ll ans = 0; 13 char ch = getchar(), last = ' '; 14 while(!isdigit(ch)) last = ch, ch = getchar(); 15 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 16 if(last == '-') ans = -ans; 17 return ans; 18 } 19 inline void write(ll x) 20 { 21 if(x < 0) x = -x, putchar('-'); 22 if(x >= 10) write(x / 10);

【csp模拟赛6】相遇--LCA

时光怂恿深爱的人放手 提交于 2019-11-30 08:18:09
对 于 3 0 % 的 数 据 : 暴 力 枚 举 判 断 对 于 6 0 % 的 数 据 : 还 是 暴 力 枚 举 , 把 两 条 路 径 都 走 一 遍 计 一 下 数 就 行 , 出 现 一 个 点 被 访 问 两 次 即 可 判 定 重 合 对 于 1 0 0 % 的 数 据 : 找 出 每 条 路 径 中 距 离 根 最 近 的 点 ( l c a ) , 判 断 这 个 点 是 否 在 另 一 条 路 径 上 即 可    注意数组大小 代码: 烟火再美,总抵不过你的一往情深 #include<iostream> #include<algorithm> #include<cstdlib> #include<cstdio> #include<cstring> #define MAXN 1000100 using namespace std; int n,m,c; int head[MAXN<<1],dep[MAXN],f[MAXN][20],cnt,T; int x1,x2,y1,y2; struct node {int nxt,to; }e[MAXN<<1]; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while

树上差分学习笔记

假如想象 提交于 2019-11-30 07:05:37
上次的动态开点线段树咕了一半。。 这次争取不咕(自己都不信 现在总结一下树上差分。 首先拿到题目你得想到树上差分(真的困难 然后有两种类型 第一种是点上的差分 ++s[x],++s[y],--s[lca(x,y)],--s[fa[lca(x,y)]]; 第二种是边上的差分 ++s[x],++s[y],s[lca(x,y)]-=2; 然后有的不单纯是++,--,带有权值修改,比如 LOJ146 https://loj.ac/problem/146 当然对于树上差分最大的问题就是把题目转化成树上差分的形式,就是想到树上差分。 (下次upd 编不下去了) 来源: https://www.cnblogs.com/Kylin-xy/p/11570695.html

PATA-1151 LCA in a Binary Tree

白昼怎懂夜的黑 提交于 2019-11-30 05:37:28
题意:根据前序和中序建立树,寻找两个点的LCA。 我在之前的博客中写了关于LCA的多种求法。 https://www.cnblogs.com/yy-1046741080/p/11505547.html 。 在建树的过程中,建立深度和parent,来寻找LCA。 该题目的数据有一定的欺诈性,它给你结点数据是1-8,如果没有仔细看清题目,那么很有可能定义一个 node tree[10005]的数组,但是题目并没有说数据范围在1-10000内。 经过测试,如果你将范围定义稍微大一点,还是能全过的; 我在这里采用的就是二叉链表,使用二叉链表麻烦的一点在于,需要查找u,v两个结点,返回其指针。 我认为最好的方法就是建立一个映射表,映射输入data和node tree[]中下标的关系,就不需要进行查找。 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 struct node { 5 int data; 6 struct node* left, * right; //left/right=-1,表示空子树 7 int depth; 8 struct node* parent; 9 }; 10 11 node* root; // 树的根 12 int pre[10005]; // 先序遍历序列 13 int in[10005]; //

[模板]最近公共祖先LCA

偶尔善良 提交于 2019-11-30 05:33:15
本人水平有限,题解不到为处,请多多谅解 本蒟蒻谢谢大家观看 题目: 传送门 倍增求LCA模板 code: #include<bits/stdc++.h> #pragma GCC optimize(3) using namespace std; int n,q,a,b,tot,m; int nxt[1000010],head[1000010],ver[1000010],dep[1000010],f[1000010][21]; //设f[x,k]表示x的2^k辈祖先,即从x向根节点走2^k步到达的节点 inline int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*f; } void put(int x,int y) { ++tot; ver[tot]=y; nxt[tot]=head[x]; head[x]=tot; } void dfs(int x,int fa)//预处理 深度及到达根节点的步数 { dep[x]=dep[fa]+1;//初始化深度 for(int i=0;i<=19;i++){//或者 i=1

树上差分学习笔记

女生的网名这么多〃 提交于 2019-11-30 04:22:57
在考了$n$次树上差分之后我终于要来学习树上差分辣.(其实今天也只是心血来潮 看的是 这篇博客 . 用来干啥的 统计点被经过的次数或者是边被经过的次数.(反正我现在暂时只知道这个$qwq$). 将一般差分中的前缀和转换成一个结点的子树和. 点的差分 差分数组$t[]$. 走过一条路径$(u,v)$.那么就$t[u]++,t[v]++,t[lca(u,v)]--,t[fa[lca(u,v)]]--$. 边的差分 转换成点的,具体来说要转换成边连接的子结点. 走过一条路径$(u,v)$.那么就$t[u]++,t[v]++,t[lca(u,v)]-=2$. 来源: https://www.cnblogs.com/forward777/p/11559501.html

【模板】lca

我是研究僧i 提交于 2019-11-30 00:58:18
int lca(int u, int v){ if(dep[u] < dep[v]) swap(u, v); for(int i = 20; i >= 0; --i){ if(dep[fa[u][i]] >= dep[v]) u = fa[u][i]; } if(u == v) return u; for(int i = 20; i >= 0; --i){ if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; } return fa[u][0]; } dep用dfs处理,dfs中顺便处理f数组 fa[u][0] = f, dep[u] = dep[f] + 1; for(int i = 1; i <= 20; ++i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; 来源: https://www.cnblogs.com/xiaobuxie/p/11542427.html

LCA倍增

北城以北 提交于 2019-11-29 22:01:25
#include <iostream> #include <cstdio> #include <vector> #include <cstring> using namespace std; const int maxn=5e5+10; int depth[maxn],fa[maxn][22],lg[maxn]; int tot; int head[maxn<<1],e[maxn<<1],nex[maxn<<1]; void add(int x,int y) { e[++tot]=y; nex[tot]=head[x]; head[x]=tot; } void dfs(int cur,int fath) { depth[cur]=depth[fath]+1; fa[cur][0]=fath; for(int i=1; (1<<i)<=depth[cur]; i++) { fa[cur][i]=fa[fa[cur][i-1]][i-1]; } for(int i=head[cur]; i!=-1; i=nex[i]) { if(e[i]==fath) continue; dfs(e[i],cur); } } int lca(int x,int y) { if(depth[x]<depth[y]) swap(x,y); while(depth[x]>depth[y]) x=fa[x]

雨天的尾巴

天大地大妈咪最大 提交于 2019-11-29 19:05:22
洛谷 线段树合并模板题 不说了直接代码分析 大佬的code #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> #include<ctime> using namespace std; #define ll long long #define N 101000 #define Z 100000 #define inf 1e9 #define RG register #define re return inline ll read(){ RG ll x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } int n,m,top,first[N],ans[N]; struct mona {int nxt,en;}s[N<<1]

天天爱跑步noip2016

这一生的挚爱 提交于 2019-11-29 19:04:08
洛谷 跟隔壁的雨天的尾巴异常相似 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1.Analysis 某条路线对当前节点x有贡献时只可能是 x在s到t的路线上(即s到lca到t) 那么首先我们可以对从s到t的路线划分为 从s到lca(s,t) 以及从t到lca a.from s to lca 要有贡献 易得dep[s]-dep[x]=val[x](出现时间) 观察可得寻找s满足dep[s]=dep[x]+val[x]的数量 b.from lca to t 要有贡献 易得dep[s]+dep[x]-dep[lca]-dep[lca]=val[x](出现时间) 观察可得寻找s满足dep[s]-dep[lca]-dep[lca]=val[x]-dep[x]的数量 为了计算.我们规定lca被算在a部分中 2.实现 a.不断从叶子到lca累加 易联想到差分 b