RMQ求LCA:使用欧拉序
点击查看代码
#include <stdio.h>
#include <string.h>
#include <ctype.h>
const int IN_SIZE = 200005, OUT_SIZE = 200005;
char inbuf[IN_SIZE + 5], *inp1 = inbuf, *inp2 = inbuf, outbuf[OUT_SIZE + 5], *outp = outbuf;
#define getchar() (inp1 == inp2 && (inp2 = (inp1 = inbuf) + fread(inbuf, 1, IN_SIZE, stdin), inp1 == inp2) ? EOF : *inp1 ++)
#define putchar(c) (*outp ++ = c, (outp - outbuf == OUT_SIZE) && (fwrite(outbuf, outp - outbuf, 1, stdout), outp = outbuf))
#define flush() (fwrite(outbuf, outp - outbuf, 1, stdout), 0)
inline int read() {
int x = 0, c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x;
}
inline void write(int x) {
static char dig[20];
static int tmp, t;
t = 0;
do tmp = x / 10, dig[++ t] = x - (tmp << 1) - (tmp << 3), x = tmp;
while(x);
for(int i = t; i; i --) putchar(dig[i] ^ 48);
}
inline int max(int x, int y) { return x > y ? x : y; }
inline int min(int x, int y) { return x < y ? x : y; }
const int N = 2e5 + 5, M = N << 1, logN = 25;
int n, m, rt, h[N], e[M], nxt[M], idx;
int st[logN][M], dfn[M], tms, id[N], lg[M];
void add(int a, int b) { e[++ idx] = b, nxt[idx] = h[a], h[a] = idx; }
void dfs(int u, int fa) {
dfn[++ tms] = u, id[u] = tms;
for(int i = h[u]; i; i = nxt[i]) {
int v = e[i];
if(v != fa) dfs(v, u), dfn[++ tms] = u;
}
}
int LCA(int x, int y) {
if(x == y) return x;
int l = min(id[x], id[y]), r = max(id[x], id[y]), t = lg[r - l + 1];
return dfn[min(st[t][l], st[t][r - (1 << t) + 1])];
}
int main() {
n = read(), m = read(), rt = read();
for(int i = 1, a, b; i < n; i ++) a = read(), b = read(), add(a, b), add(b, a);
dfs(rt, 0);
lg[0] = -1; for(int i = 1; i <= tms; i ++) lg[i] = lg[i >> 1] + 1, st[0][i] = id[dfn[i]];
for(int j = 1; j < logN; j ++)
for(int i = 1; i + (1 << j) - 1 <= tms; i ++)
st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
for(int i = 1, a, b, c = 0; i <= m; i ++)
a = (read() + c) % n + 1, b = (read() + c) % n + 1, write(c = LCA(a, b)), putchar(10);
return flush();
}