「vijos」lxhgww的奇思妙想(长链剖分)
长链剖分的板子(又是乱搞优化暴力)
对于每一个点,我们定义它深度最深的子节点为它的重儿子(为什么不叫长儿子……),他们之间的连边为重边
然后长链剖分有几个性质
1.总链长为$O(n)$
2.一个节点的$k$级祖先的子树深度必定大于等于当前节点的子树深度
以上两点稍微yy一下就能发现是对的
然后回到这道题。我们设$len[u]$为这一条长链的长度,对于每一个长链的顶点,我们维护它的1到$len[u]$级儿子以及1到$len[u]$级祖先
同时预处理找祖先的倍增数组,并预处理出1到$n$的每一个数字的二进制最高位即$highbit$
那么对于每一个询问$(u,k)$,我们设$r=highbit(k)$,那么我们用预处理的倍增数组让$u$跳到它的$r$级祖先$v$处
因为$k-r<r$,那么$v$的长链的长度$\geq r>k-r$,那么$v$所在的长链预处理的表一定已经包含了$u$的$k$级祖先
时间复杂度为$O(nlogn+m)$,预处理$O(nlogn)$,每一次回答$O(1)$
//minamoto
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=3e5+;
int head[N],Next[N<<],ver[N<<],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int n,md[N],dep[N],fa[N][],son[N],top[N],len[N],B[N];
vector<int> U[N],D[N];
void dfs(int u,int f){
md[u]=dep[u]=dep[f]+,fa[u][]=f;
for(int i=;i<;++i)
if(fa[u][i-]) fa[u][i]=fa[fa[u][i-]][i-];
else break;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=f){
dfs(v,u);
if(md[son[u]]<md[v]) son[u]=v,md[u]=md[v];
}
}
}
void dfs2(int u,int t){
top[u]=t,len[u]=md[u]-dep[t]+;
if(son[u]){
dfs2(son[u],t);
for(int i=head[u];i;i=Next[i])
if(!top[ver[i]]) dfs2(ver[i],ver[i]);
}
}
void init(){
int now=;
for(int i=;i<=n;++i){
if(!(i&(<<now))) ++now;
B[i]=now;
}
for(int i=;i<=n;++i)
if(i==top[i]){
for(int j=,u=i;j<=len[i]&&u;++j) u=fa[u][],U[i].push_back(u);
for(int j=,u=i;j<=len[i]&&u;++j) u=son[u],D[i].push_back(u);
}
}
int query(int u,int k){
if(k>dep[u]) return ;if(k==) return u;
u=fa[u][B[k]],k^=<<B[k];
if(k==) return u;
if(dep[u]-dep[top[u]]==k) return top[u];
if(dep[u]-dep[top[u]]<k) return U[top[u]][k-dep[u]+dep[top[u]]-];
else return D[top[u]][dep[u]-dep[top[u]]-k-];
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs(,),dfs2(,),init();
int lastans=,q=read();
while(q--){
int u=read()^lastans,v=read()^lastans;
printf("%d\n",lastans=query(u,v));
}
return Ot(),;
}
「vijos」lxhgww的奇思妙想(长链剖分)的更多相关文章
- 「vijos-bashu」lxhgww的奇思妙想(长链剖分)
倍增离线,预处理出爹和孙子们.查询\(O(1)\) #include <cstdio> #include <cstring> #include <numeric> ...
- [vijos]lxhgww的奇思妙想(长链剖分)
题意 题目链接 Sol 长链剖分 又是一个用各种花式技巧优化的暴力 它的主要思想是:对于每个节点,把深度最深的子节点当做重儿子,它们之间的边当做重边 这样就会有一些非常好的轻质 所有链长总和是\(O( ...
- lxhgww的奇思妙想 长链剖分板子
https://vijos.org/d/Bashu_OIers/p/5a79a3e1d3d8a103be7e2b81 求k级祖先,预处理nlogn,查询o1 //#pragma GCC optimiz ...
- 「HAOI2015」「LuoguP3178」树上操作(树链剖分
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- 「LuoguP3384」【模板】树链剖分
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- 【Vijos】lxhgww的奇思妙想(长链剖分)
题面 给定一棵树,每次询问一个点的\(k\)次祖先,强制在线. Vijos 题解 长链剖分. 链接暂时咕咕咕了. 现在可以戳链接看题解了 #include<iostream> #inclu ...
- Vijos.lxhgww的奇思妙想(k级祖先 长链剖分)
题目链接 https://blog.bill.moe/long-chain-subdivision-notes/ http://www.cnblogs.com/zzqsblog/p/6700133.h ...
- 2019.01.06 vijos lxhgww的奇思妙想(长链剖分)
传送门 长链剖分模板题. 题意简述:允许O(nlogn)O(nlog_n)O(nlogn)预处理,让你支持O(1)O(1)O(1)查找任意一个点的kkk级祖先. 思路:因为要O(1)O(1)O(1) ...
- 【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)
[COGS2652]秘术「天文密葬法」(长链剖分,分数规划) 题面 Cogs 上面废话真多,建议直接拉到最下面看一句话题意吧: 给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σa ...
随机推荐
- Event Logging 技术简介
https://blog.csdn.net/xiliang_pan/article/details/41805023
- [Poj2411]Mondriaan's Dream(状压dp)(插头dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18096 Accepted: 103 ...
- java基础编程题
1. 某公司每月标准上班时间是160小时,每小时工资是30元. 如果上班时间超出了160小时,超出部分每小时按1.5倍工资发放.请编写程序计算员工月工资. package com.num2.lianx ...
- Log4j的日志级别分析(转)
说明:Log4j的日志是有级别的,从低到高顺序为:ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF,当定义了日志级别为 ...
- hdu 3624 City Planning(暴力,也可扫描线)
City Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 【python】对象和面向对象
类的定义 python支持多重继承,在类名后面的小括号中,可以列出多个类名,以逗号分割. __init__方法在类的实例创建后被立即调用,注意与c++中构造函数不一样,因为对象在调用__init__时 ...
- python绘图入门
python绘图入门 学习了:https://zhuanlan.zhihu.com/p/34200452 API:https://matplotlib.org/api/pyplot_api.html ...
- leetcode ----Trie/stack专题
一:Implement Trie (Prefix Tree) 题目: Implement a trie with insert, search, and startsWith methods. Not ...
- ABP框架 - 介绍 VS2017调试器无法附加到IIS进程(w3wp.exe) c# 动态实例化一个泛型类
ABP框架 - 介绍 在14,15年间带领几个不同的团队,交付了几个项目,在这个过程中,虽然几个项目的业务不一样,但是很多应用程序架构基础性的功能却是大同小异,例如认证.授权.请求验证.异常处理. ...
- 在类的头文件里尽量少引入其它头文件 <<Effective Objective-C>>
与C 和C++ 一样,Objective-C 也使用"头文件"(header file) 与"实现文件"(implementation file)来区隔代码.用 ...