lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs
Posted cmyg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ",a[ f[x][d] ]); 109 else 110 printf("%d ",a[ f[j][d] ]); 111 // printf("%d ",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 ",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 ",r[i]); 122 return 0; 123 }
以上是关于lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs的主要内容,如果未能解决你的问题,请参考以下文章