lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379
1.欧拉序+rmq(st)
1 /* 2 在这里,对于一个数,选择最左边的 3 选择任意一个都可以,[left_index,right_index],深度都大于等于这个数的深度 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <cmath> 8 #include <cstring> 9 #include <time.h> 10 #include <string> 11 #include <set> 12 #include <map> 13 #include <list> 14 #include <stack> 15 #include <queue> 16 #include <vector> 17 #include <bitset> 18 #include <ext/rope> 19 #include <algorithm> 20 #include <iostream> 21 using namespace std; 22 #define ll long long 23 #define minv 1e-6 24 #define inf 1e9 25 #define pi 3.1415926536 26 #define E 2.7182818284 27 const ll mod=1e9+7;//998244353 28 const int maxn=5e5+10; 29 30 struct node 31 { 32 int d; 33 node *next; 34 }*e[maxn]; 35 36 int s=0; 37 38 ///每条边走两遍,n-1条边,走2(n-1)个点 39 int a[maxn<<1],b[maxn<<1],f[maxn<<1][20],lef[maxn],er[20]; 40 bool vis[maxn]={0}; 41 42 void dfs(int d,int dep) 43 { 44 node* p=e[d]; 45 vis[d]=1; 46 s++; 47 lef[d]=s; 48 a[s]=d; 49 b[s]=dep; 50 while (p) 51 { 52 if (!vis[p->d]) 53 { 54 dfs(p->d,dep+1); 55 s++; 56 a[s]=d; 57 b[s]=dep; 58 } 59 p=p->next; 60 } 61 } 62 63 int main() 64 { 65 int n,q,root,x,y,i,j,k,m,d; 66 node *p; 67 scanf("%d%d%d",&n,&q,&root); 68 for (i=1;i<n;i++) 69 { 70 scanf("%d%d",&x,&y); 71 p=(node*) malloc (sizeof(node)); 72 p->d=y; 73 p->next=e[x]; 74 e[x]=p; 75 76 p=(node*) malloc (sizeof(node)); 77 p->d=x; 78 p->next=e[y]; 79 e[y]=p; 80 } 81 dfs(root,1); 82 83 m=log(s)/log(2); 84 er[0]=1; 85 for (i=1;i<=m;i++) 86 er[i]=er[i-1]<<1; 87 for (i=1;i<=s;i++) 88 f[i][0]=i; 89 // f[i][0]=b[i]; 90 for (i=1;i<=m;i++) //2^i 91 for (j=1,k=j+er[i-1];j<=s-er[i]+1;j++,k++) //-er[i]+1 92 if (b[ f[j][i-1] ] < b[ f[k][i-1] ]) 93 f[j][i]=f[j][i-1]; 94 else 95 f[j][i]=f[k][i-1]; 96 // f[j][i]=min(f[j][i-1],f[j+er[i-1]][i-1]); 97 98 while (q--) 99 { 100 scanf("%d%d",&x,&y); 101 x=lef[x]; 102 y=lef[y]; 103 if (x>y) 104 swap(x,y); 105 d=log(y-x+1)/log(2); 106 j=y-er[d]+1; 107 if (b[ f[x][d] ] < b[ f[j][d] ]) //+1 108 printf("%d\n",a[ f[x][d] ]); 109 else 110 printf("%d\n",a[ f[j][d] ]); 111 // printf("%d\n",min(f[x][d],f[y-er[d]+1][d])); 112 } 113 return 0; 114 } 115 /* 116 8 100 1 117 1 2 118 1 3 119 2 4 120 2 5 121 3 6 122 5 7 123 6 8 124 125 5 7 126 5 127 2 3 128 1 129 3 2 130 1 131 1 8 132 1 133 2 8 134 1 135 4 5 136 2 137 5 4 138 2 139 */
2.欧拉序+线段树
1 /* 2 在这里,对于一个数,选择最左边的 3 选择任意一个都可以,[left_index,right_index],深度都大于等于这个数的深度 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <cmath> 8 #include <cstring> 9 #include <time.h> 10 #include <string> 11 #include <set> 12 #include <map> 13 #include <list> 14 #include <stack> 15 #include <queue> 16 #include <vector> 17 #include <bitset> 18 #include <ext/rope> 19 #include <algorithm> 20 #include <iostream> 21 using namespace std; 22 #define ll long long 23 #define minv 1e-6 24 #define inf 1e9 25 #define pi 3.1415926536 26 #define E 2.7182818284 27 const ll mod=1e9+7;//998244353 28 const int maxn=5e5+10; 29 30 struct node 31 { 32 int d; 33 node *next; 34 }*e[maxn]; 35 36 int s=0; 37 38 ///每条边走两遍,n-1条边,走2(n-1)个点 39 int a[maxn<<1],b[maxn<<1],lef[maxn],f[maxn<<3]; 40 bool vis[maxn]={0}; 41 int num=0; 42 43 void dfs(int d,int dep) 44 { 45 node* p=e[d]; 46 vis[d]=1; 47 s++; 48 lef[d]=s; 49 a[s]=d; 50 b[s]=dep; 51 while (p) 52 { 53 if (!vis[p->d]) 54 { 55 dfs(p->d,dep+1); 56 s++; 57 a[s]=d; 58 b[s]=dep; 59 } 60 p=p->next; 61 } 62 } 63 64 void build(int index,int l,int r) 65 { 66 if (l==r) 67 f[index]=++num; 68 else 69 { 70 int m=(l+r)>>1; 71 build(index<<1,l,m); 72 build(index<<1|1,m+1,r); 73 if (b[f[index<<1]]<b[f[index<<1|1]]) 74 f[index]=f[index<<1]; 75 else 76 f[index]=f[index<<1|1]; 77 } 78 } 79 80 int query(int index,int l,int r,int x,int y) 81 { 82 if (x<=l && r<=y) 83 return f[index]; 84 if (r<x || l>y) 85 return 0; 86 int m=(l+r)>>1; 87 int p=query(index<<1,l,m,x,y); 88 int q=query(index<<1|1,m+1,r,x,y); 89 if (b[p]<b[q]) 90 return p; 91 else 92 return q; 93 } 94 95 int main() 96 { 97 int n,q,root,x,y,i,j,m,d; 98 node *p; 99 scanf("%d%d%d",&n,&q,&root); 100 for (i=1;i<n;i++) 101 { 102 scanf("%d%d",&x,&y); 103 p=(node*) malloc (sizeof(node)); 104 p->d=y; 105 p->next=e[x]; 106 e[x]=p; 107 108 p=(node*) malloc (sizeof(node)); 109 p->d=x; 110 p->next=e[y]; 111 e[y]=p; 112 } 113 dfs(root,1); 114 115 b[0]=n+1; 116 build(1,1,s); 117 while (q--) 118 { 119 scanf("%d%d",&x,&y); 120 x=lef[x]; 121 y=lef[y]; 122 if (x>y) 123 swap(x,y); 124 printf("%d\n",a[query(1,1,s,x,y)]); 125 } 126 return 0; 127 }
3.离线dfs
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define E 2.7182818284 23 const ll mod=1e9+7;//998244353 24 const int maxn=5e5+10; 25 26 struct node 27 { 28 int d; 29 node *next; 30 }*e[maxn]; 31 struct rec 32 { 33 int d,index; 34 rec *next; 35 }*ask[maxn]; 36 bool vis[maxn]={0}; 37 38 int r[maxn],fa[maxn]; 39 40 int getfather(int d) 41 { 42 if (fa[d]==d) 43 return d; 44 fa[d]=getfather(fa[d]); 45 return fa[d]; 46 } 47 48 void merge(int x,int y) 49 { 50 int s=getfather(x); 51 int t=getfather(y); 52 fa[t]=s; 53 } 54 55 void dfs(int d) 56 { 57 node *p; 58 rec *v; 59 vis[d]=1; 60 61 p=e[d]; 62 while (p) 63 { 64 if (!vis[p->d]) 65 { 66 dfs(p->d); 67 merge(d,p->d); 68 } 69 p=p->next; 70 } 71 72 v=ask[d]; 73 while (v) 74 { 75 if (vis[v->d]) 76 r[v->index]=getfather(v->d); 77 v=v->next; 78 } 79 } 80 81 int main() 82 { 83 node *p; 84 rec *v; 85 int n,q,root,x,y,i; 86 scanf("%d%d%d",&n,&q,&root); 87 for (i=1;i<n;i++) 88 { 89 scanf("%d%d",&x,&y); 90 p=(node*) malloc (sizeof(node)); 91 p->d=y; 92 p->next=e[x]; 93 e[x]=p; 94 95 p=(node*) malloc (sizeof(node)); 96 p->d=x; 97 p->next=e[y]; 98 e[y]=p; 99 } 100 101 for (i=1;i<=q;i++) 102 { 103 scanf("%d%d",&x,&y); 104 v=(rec*) malloc (sizeof(rec)); 105 v->d=y; 106 v->index=i; 107 v->next=ask[x]; 108 ask[x]=v; 109 110 v=(rec*) malloc (sizeof(rec)); 111 v->d=x; 112 v->index=i; 113 v->next=ask[y]; 114 ask[y]=v; 115 } 116 117 for (i=1;i<=n;i++) 118 fa[i]=i; 119 dfs(root); 120 for (i=1;i<=q;i++) 121 printf("%d\n",r[i]); 122 return 0; 123 }
4.倍增
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define nl 2.7182818284 23 const ll mod=1e9+7;//998244353 24 const int maxn=5e5+10; 25 26 struct node 27 { 28 int d; 29 node *next; 30 }*e[maxn]; 31 32 bool vis[maxn]={0}; 33 int q[maxn],dep[maxn],f[maxn][20]; 34 35 int main() 36 { 37 node *p; 38 int n,Q,root,head,tail,x,y,d,dd,i,j,k; 39 scanf("%d%d%d",&n,&Q,&root); 40 for (i=1;i<n;i++) 41 { 42 scanf("%d%d",&x,&y); 43 p=new node(); 44 p->d=y; 45 p->next=e[x]; 46 e[x]=p; 47 48 p=new node(); 49 p->d=x; 50 p->next=e[y]; 51 e[y]=p; 52 } 53 54 head=0,tail=1; 55 vis[root]=1; 56 q[1]=root; 57 dep[root]=0; 58 while (head<tail) 59 { 60 head++; 61 d=q[head]; 62 p=e[d]; 63 while (p) 64 { 65 dd=p->d; 66 if (!vis[dd]) 67 { 68 tail++; 69 q[tail]=dd; 70 vis[dd]=1; 71 dep[dd]=dep[d]+1; 72 //f[dd][0]=d; 73 74 j=d; 75 k=0; 76 while (j) 77 { 78 f[dd][k]=j; 79 j=f[j][k]; 80 k++; 81 } 82 } 83 p=p->next; 84 } 85 } 86 while (Q--) 87 { 88 scanf("%d%d",&x,&y); 89 if (dep[x]<dep[y]) 90 swap(x,y); 91 92 i=dep[x]-dep[y]; 93 j=0; 94 while (i) 95 { 96 if (i & 1) 97 x=f[x][j]; 98 i>>=1; 99 j++; 100 } 101 102 if (dep[x]==0) 103 k=0; 104 else 105 k=log(dep[x]+minv)/log(2)+1; 106 i=(1<<k); 107 while (k) 108 { 109 k--; 110 i>>=1; 111 if (dep[x]>=i && f[x][k]!=f[y][k]) 112 { 113 x=f[x][k]; 114 y=f[y][k]; 115 } 116 } 117 if (x!=y) 118 x=f[x][0]; 119 printf("%d\n",x); 120 } 121 return 0; 122 } 123 /* 124 5 100 1 125 1 2 126 2 3 127 3 4 128 4 5 129 130 1 5 131 3 4 132 2 4 133 2 5 134 135 136 7 100 1 137 1 2 138 2 3 139 2 4 140 4 5 141 4 6 142 1 7 143 144 5 7 145 3 7 146 5 1 147 2 6 148 3 6 149 150 10 100 1 151 1 2 152 2 3 153 3 4 154 4 5 155 5 6 156 6 7 157 7 8 158 8 9 159 9 10 160 161 1 10 162 2 10 163 3 10 164 4 10 165 5 9 166 7 8 167 168 10 100 1 169 1 2 170 2 3 171 3 4 172 3 5 173 5 6 174 5 7 175 2 8 176 8 9 177 9 10 178 179 6 10 180 4 10 181 3 1 182 6 7 183 3 10 184 2 10 185 3 7 186 6 7 187 4 7 188 189 190 10 100 1 191 1 2 192 1 3 193 1 4 194 3 5 195 3 6 196 3 7 197 7 8 198 7 9 199 7 10 200 201 15 100 1 202 1 2 203 2 3 204 3 4 205 4 5 206 5 6 207 6 7 208 7 8 209 8 9 210 9 10 211 10 11 212 11 12 213 12 13 214 13 14 215 14 15 216 217 1 15 218 2 15 219 2 14 220 3 14 221 3 13 222 4 13 223 4 12 224 225 226 12 100 1 227 1 2 228 2 3 229 3 4 230 4 5 231 5 6 232 1 7 233 7 8 234 8 9 235 9 10 236 10 11 237 11 12 238 239 6 12 240 4 7 241 8 12 242 1 6 243 */