XSY2414CF587CDuff in the Army(倍增lca)
Posted ez-lcw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XSY2414CF587CDuff in the Army(倍增lca)相关的知识,希望对你有一定的参考价值。
看到题目中\(a<=0\),自然就想到用暴力维护这个东东。
设倍增数组\(fa[u][i]\)和\(minn[u][i]\),其中\(minn\)存的是一个结构体,结构体中包含两个东东:一个数组和这个数组中的元素个数。
\(fa[u][i]\)表示啥我就不说了,\(minn[u][i]\)表示从\(u\)到\(fa[u][i]\)(即\(u\)的\(i\)倍祖先)中前\(10\)小的值。
合并就暴力合并,每次看哪个小就加哪个,查找就按\(lca\)的方式查找。
说实话挺暴力的
最后的代码+注释如下:
#include<bits/stdc++.h>
#define N 100010
#define A 15
#define K 20
#define INF 0x7fffffff
using namespace std;
struct data
int tot,num[A];
void init()
for(int i=1;i<=11;i++)
num[i]=INF;
void add(int x)
if(tot==10)
return;
num[++tot]=x;//为啥add时不用排序?因为主程序中插入时就是有序的
t[N],minn[N][K],none;
int n,m,q;
int cnt,head[N],nxt[N<<1],to[N<<1];
int fa[N][K],d[N];
void adde(int u,int v)
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
data merge(data a,data b,int t=10)//暴力merge
data c=none;
int x=1,y=1;
while(x<=a.tot&&y<=b.tot&&c.tot<t)
if(a.num[x]<b.num[y])c.num[++c.tot]=a.num[x++];
else c.num[++c.tot]=b.num[y++];
while(x<=a.tot&&c.tot<t)
c.num[++c.tot]=a.num[x++];
while(y<=b.tot&&c.tot<t)
c.num[++c.tot]=b.num[y++];
return c;
void dfs(int u)
for(int i=1;i<=17;i++)//合并倍增数组
fa[u][i]=fa[fa[u][i-1]][i-1];
minn[u][i]=merge(minn[u][i-1],minn[fa[u][i-1]][i-1]);
for(int i=head[u];i;i=nxt[i])
if(to[i]!=fa[u][0])
d[to[i]]=d[u]+1;
fa[to[i]][0]=u;
minn[to[i]][0]=t[u];
dfs(to[i]);
data lca(int a,int b,int x)
data ans=none;
if(d[a]<d[b])swap(a,b);
ans=merge(ans,t[a],x);
for(int i=17;i>=0;i--)
if(d[a]-(1<<i)>=d[b])
ans=merge(ans,minn[a][i],x),a=fa[a][i];
if(a==b)
return ans;
ans=merge(ans,t[b],x);
for(int i=17;i>=0;i--)
if(fa[a][i]!=fa[b][i])
ans=merge(ans,merge(minn[a][i],minn[b][i],x),x);
a=fa[a][i],b=fa[b][i];
ans=merge(ans,minn[a][0],x);
return ans;
int main()
none.init();
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++)
t[i].init();
for(int i=1;i<n;i++)
int u,v;
scanf("%d%d",&u,&v);
adde(u,v),adde(v,u);
for(int i=1;i<=m;i++)
int c;
scanf("%d",&c);
t[c].add(i);
dfs(1);
while(q--)
int u,v,a;
scanf("%d%d%d",&u,&v,&a);
data t=lca(u,v,a);
if(t.tot)
printf("%d ",t.tot);
for(int i=1;i<=t.tot;i++)
printf("%d ",t.num[i]);
puts("");
else
puts("0");
return 0;
以上是关于XSY2414CF587CDuff in the Army(倍增lca)的主要内容,如果未能解决你的问题,请参考以下文章