现有一棵树。您需要写一个树上倍增算法,以实现如下操作:
A x 新建一个节点,将它作为x节点的儿子,编号为当前节点总数+1。
Q k p1 p2 p3.... 查询p1,p2,p3...这些节点的LCA。其中k表示查询节点的个数。
最初树上只有一个节点,编号为1。
多个节点的LCA定义为:这些节点的公共祖先中深度最大的。
标签:scanf get == blank name 题目 algo script .com
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int bin[25],fa[3000010][21],dep[3000100]; int n,Q,m; char st[51]; int a[3100]; bool cmp(int x,int y){return dep[x]>dep[y];} bool check(int j) { for(int i=1;i<m;i++)if(fa[a[i]][j]!=fa[a[i+1]][j])return true; return false; } int main() { scanf("%d",&Q); bin[0]=1;for(int i=1;i<=24;i++)bin[i]=bin[i-1]<<1; dep[1]=1;fa[1][0]=0;n=1; while(Q--) { scanf("%s%d",st+1,&m); if(st[1]==‘A‘) { n++;int f=m; dep[n]=dep[f]+1;fa[n][0]=f; for(int i=1;bin[i]<=dep[n];i++)fa[n][i]=fa[fa[n][i-1]][i-1]; } else { for(int i=1;i<=m;i++)scanf("%d",&a[i]); sort(a+1,a+1+m,cmp); for(int i=20;i>=0;i--) for(int j=1;j<m;j++) if(bin[i]<=dep[a[j]]&&dep[fa[a[j]][i]]>=dep[a[m]])a[j]=fa[a[j]][i]; bool bk=true; for(int i=2;i<=m;i++)if(a[i]!=a[i-1]){bk=false;break;} if(bk==true){printf("%d\n",a[1]);continue;} for(int i=20;i>=0;i--) if(bin[i]<=dep[a[1]]&&check(i)==true) for(int j=1;j<=m;j++) a[j]=fa[a[j]][i]; printf("%d\n",fa[a[1]][0]); } } return 0; }
by_lmy
标签:scanf get == blank name 题目 algo script .com
原文地址:https://www.cnblogs.com/MT-LI/p/8757409.html