离线trajan:
int find(int x)
{
if(x==pre[x])return x;
return pre[x]=find(pre[x]);
}
void unite(int a,int b)
{
int x=find(x),y=find(b);
pre[y]=x;
}
void LCA(int u)
{
pre[u]=u;
ance[u]=u;
vis[u]=1;
int len=g[u].size();
for(int i=0;i<len;i++)
{
int v=g[u][i].first;
int w=g[u][i].second;
if(vis[v])continue;
dis[v]=dis[u]+w;
LCA(v);
unite(u,v);
ance[find(v)]=u;
}
len=q[u].size();
for(int i=0;i<len;i++)
{
int v=q[u][i].second;
int x=ance[find(v)];
if(vis[v])
ans[q[u][i].first]=dis[v]+dis[u]-2*dis[x];
}
}
在线RMQ:
void init()
{
for(int i=0;i<=n;i++)g[i].clear();
num=0;
memset(pos,-1,sizeof(pos));
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
}
void dfs(int u,int depth)
{
E[++num]=u,dep[num]=depth;
if(pos[u]==-1)pos[u]=num;
vis[u]=1;
int len=g[u].size();
for(int i=0;i<len;i++)
{
int v=g[u][i].first;
int w=g[u][i].second;
if(vis[v])continue;
dis[v]=dis[u]+w;
dfs(v,depth+1);
E[++num]=u;
dep[num]=depth;
}
}
void initRMQ(int len)
{
for(int i=0;i<=len;i++)d[i][0]=i;
for(int j=1;(1<<j)<=len;j++)
for(int i=1;i+(1<<j)<=len;i++)
{
int x=d[i][j-1],y=d[i+(1<<(j-1))][j-1];
if(dep[x]<=dep[y])d[i][j]=x;
else d[i][j]=y;
}
}
int LCA(int x,int y)
{
int a=pos[x],b=pos[y];
if(a>b)swap(a,b);
int k=0;
while((1<<(k+1))<=b-a+1)k++;
int l=d[a][k],r=d[b-(1<<k)+1][k];
if(dep[l]<dep[r])return E[l];
return E[r];
}
在线lrj版:
vector<int> edge[maxn];
int dep[maxn],fa[maxn],anc[maxn][30];
int num[maxn];
void dfs(int u,int f,int depth)
{
dep[u]=depth;
fa[u]=f;
num[u]=1;
int len=edge[u].size();
for(int i=0;i<len;i++)
{
int v=edge[u][i];
if(v==f)continue;
dfs(v,u,depth+1);
num[u]+=num[v];
fa[v]=u;
}
}
void preprocess()
{
for(int i=1;i<=N;i++)
{
anc[i][0]=fa[i];
for(int j=1;(1<<j)<=N;j++)anc[i][j]=-1;
}
for(int j=1;(1<<j)<=N;j++)
{
for(int i=1;i<=N;i++)
{
if(anc[i][j-1]==-1)continue;
int a=anc[i][j-1];
anc[i][j]=anc[a][j-1];
}
}
}
int LCA(int p,int q)
{
if(dep[p]<dep[q])swap(p,q);
int k=0;
while((1<<(k+1))<=dep[p])k++;
for(int i=k;i>=0;i--)
if(dep[p]-(1<<i)>=dep[q])
p=anc[p][i];
if(p==q)return p;
for(int i=k;i>=0;i--)
if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i])
p=anc[p][i],q=anc[q][i];
return fa[p];
}
//往上走dis步
int jump(int u,int dis)
{
if(dis==0)return u;
for(int i=19;i>=0;i--)
if((1<<i)<=dis)
u=anc[u][i],dis-=(1<<i);
return u;
}