1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
#define REG register #define IN inline #define For(x,y,z) for (REG int (x) = (y); (x) <= (z); ++(x)) #define FOR(x,y,z) for (REG int (x) = (y); (x) < (z); ++(x)) const int kmax_num = 1e5 + 10, kmax_int = INT_MAX, kmod = 1e9 + 7;
int n, q;
struct { int v, next; } edges[kmax_num * 2];
int cnt, head[kmax_num];
inline void AddEdge(const int& u, const int& v) { edges[++cnt] = (Edge) {v, head[u]}; head[u] = cnt; edges[++cnt] = (Edge) {u, head[v]}; head[v] = cnt; return ; }
int dep[kmax_num]; int f[33][kmax_num];
inline void GetDepth(const int& u, REG int depth) { dep[u] = depth; for(REG int i = head[u]; i; i = edges[i].next) { if(!dep[edges[i].v]) GetDepth(edges[i].v, depth + 1), f[0][edges[i].v] = u; } return ; }
int lg[kmax_num];
inline void Init() { FOR(i,2,kmax_num) lg[i] = lg[i - 1] + (1 << lg[i - 1] + 1 == i);
for(REG int i = 1; (1 << i) <= n; ++i) { For(h,1,n) f[i][h] = f[i - 1][f[i - 1][h]]; } return ; }
inline int LCA(REG int x, REG int y) { if(dep[x] < dep[y]) std::swap(x, y); while(dep[x] != dep[y]) x = f[lg[dep[x] - dep[y]]][x];
if(x == y) return x;
for(REG int i = lg[dep[x]]; i >= 0; --i) if(f[i][x] != f[i][y]) x = f[i][x], y = f[i][y]; return f[0][x]; }
inline int GetDist(const int& x, const int& y) { REG int anc = LCA(x, y); return dep[x] + dep[y] - (dep[anc] << 1); }
int main() { std::cin >> n >> q;
int u, v; FOR(i,1,n) { AIOS::file_io >> u >> v; AddEdge(u, v); } GetDepth(1, 1); Init();
int a, b, c, d; For(i,1,q) { AIOS::file_io >> a >> b >> c >> d; if(GetDist(a, b) + GetDist(c, d) >= GetDist(a, c) + GetDist(b, d)) puts("Y"); else puts("N"); } return 0; }
|
近期评论