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 */

 

posted @ 2018-08-27 22:33  congmingyige  阅读(306)  评论(0编辑  收藏  举报