传送门

长链剖分的板子(又是乱搞优化暴力)

对于每一个点,我们定义它深度最深的子节点为它的重儿子(为什么不叫长儿子……),他们之间的连边为重边

然后长链剖分有几个性质

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的奇思妙想(长链剖分)的更多相关文章

  1. 「vijos-bashu」lxhgww的奇思妙想(长链剖分)

    倍增离线,预处理出爹和孙子们.查询\(O(1)\) #include <cstdio> #include <cstring> #include <numeric> ...

  2. [vijos]lxhgww的奇思妙想(长链剖分)

    题意 题目链接 Sol 长链剖分 又是一个用各种花式技巧优化的暴力 它的主要思想是:对于每个节点,把深度最深的子节点当做重儿子,它们之间的边当做重边 这样就会有一些非常好的轻质 所有链长总和是\(O( ...

  3. lxhgww的奇思妙想 长链剖分板子

    https://vijos.org/d/Bashu_OIers/p/5a79a3e1d3d8a103be7e2b81 求k级祖先,预处理nlogn,查询o1 //#pragma GCC optimiz ...

  4. 「HAOI2015」「LuoguP3178」树上操作(树链剖分

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...

  5. 「LuoguP3384」【模板】树链剖分

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  6. 【Vijos】lxhgww的奇思妙想(长链剖分)

    题面 给定一棵树,每次询问一个点的\(k\)次祖先,强制在线. Vijos 题解 长链剖分. 链接暂时咕咕咕了. 现在可以戳链接看题解了 #include<iostream> #inclu ...

  7. Vijos.lxhgww的奇思妙想(k级祖先 长链剖分)

    题目链接 https://blog.bill.moe/long-chain-subdivision-notes/ http://www.cnblogs.com/zzqsblog/p/6700133.h ...

  8. 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) ...

  9. 【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)

    [COGS2652]秘术「天文密葬法」(长链剖分,分数规划) 题面 Cogs 上面废话真多,建议直接拉到最下面看一句话题意吧: 给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σa ...

随机推荐

  1. 检测socket链接是否断开

    [解决方案]   1. 发送重试,由业务完成.     因为club_l5的send接口不会保留用户发送的内容,在recv失败的情况下,用户发送的数据已经丢失,所以只能由业务进行重试.     结论: ...

  2. Meteor集合

    在本教程中,我们将学习如何使用 MongoDB集合. 创建集合 我们可以使用以下代码来创建一个新的集合- meteorApp/client/main.js MyCollection = new Mon ...

  3. 关于rman duplicate 一些比較重要的知识点--系列三

    FYI: http://docs.oracle.com/cd/E11882_01/backup.112/e10643/rcmsynta020.htm#RCMRF126 rman duplicate d ...

  4. cocos2d-x进化为2.5D的一些想法

     首先我得说Unity3D已经做的非常好了,搞这些东西意义真心不大.详细Unity3D有什么优势我之前也写过两篇文章来阐述自己的想法.         假设我的下一份工作是U3D的话,预计我就不会 ...

  5. 怎样使用SSH连接OpenStack上的云主机

    转载请注明出处.否则将追究法律责任http://blog.csdn.net/xingjiarong/article/details/47021815 在上一篇博客中我介绍了怎样在OpenStack中创 ...

  6. ubuntu安装nginx时提示error: the HTTP rewrite module requires the PCRE library

    ubuntu安装nginx时提示error: the HTTP rewrite module requires the PCRE library 须要安装pcre包. sudo apt-get upd ...

  7. sqlserver中All、Any和Some用法与区别

    转自:http://blog.csdn.net/gyc1105/article/details/8063624 SQLServer中有三个关键字可以修改比较运算符:All.Any和Some,其中Som ...

  8. Windows7 64bits下安装TensorFlow GPU版本(图文详解)

    不多说,直接上干货! Installing TensorFlow on Windows的官网 https://www.tensorflow.org/install/install_windows 首先 ...

  9. STL_算法_最小值和最大值(min_element、max_element)

    C++ Primer 学习中... 简单记录下我的学习过程 (代码为主) min_element.max_element  找最小.最大值. 非常easy没什么大作用 #include<iost ...

  10. [iOS]经常使用正則表達式

    经常使用正則表達式大全!(比如:匹配中文.匹配html) 匹配中文字符的正則表達式: [u4e00-u9fa5]    评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包含汉字 ...