倍增

1.

lca模板题

https://www.luogu.org/problemnew/show/P3379

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

2.

http://hihocoder.com/problemset/problem/1384

原文地址:https://www.cnblogs.com/cmyg/p/9562819.html