梦游中的你来到了一棵 N 个节点的树上.
你一共做了 Q 个梦, 每个梦需要你从点 u 走到点 v 之后才能苏醒,
由于你正在梦游, 所以每到一个节点后,你会在它连出去的边中等概率地选择一条走过去,
为了确保第二天能够准时到校, 你要求出每个梦期望经过多少条边才能苏醒.
为了避免精度误差, 你要输出答案模10^9 + 7的结果.
对于 20%的数据, N <= 10.
对于 40%的数据, N <= 1000.
另有 20%的数据, 保证给定的树是一条链.
对于 100%的数据, N <= 100000, Q <= 100000.
1 %:pragma GCC optimize(2) 2 %:pragma GCC optimize(3) 3 %:pragma GCC optimize("Ofast") 4 %:pragma GCC optimize("inline") 5 %:pragma GCC optimize("-fgcse") 6 %:pragma GCC optimize("-fgcse-lm") 7 %:pragma GCC optimize("-fipa-sra") 8 %:pragma GCC optimize("-ftree-pre") 9 %:pragma GCC optimize("-ftree-vrp") 10 %:pragma GCC optimize("-fpeephole2") 11 %:pragma GCC optimize("-ffast-math") 12 %:pragma GCC optimize("-fsched-spec") 13 %:pragma GCC optimize("unroll-loops") 14 %:pragma GCC optimize("-falign-jumps") 15 %:pragma GCC optimize("-falign-loops") 16 %:pragma GCC optimize("-falign-labels") 17 %:pragma GCC optimize("-fdevirtualize") 18 %:pragma GCC optimize("-fcaller-saves") 19 %:pragma GCC optimize("-fcrossjumping") 20 %:pragma GCC optimize("-fthread-jumps") 21 %:pragma GCC optimize("-funroll-loops") 22 %:pragma GCC optimize("-fwhole-program") 23 %:pragma GCC optimize("-freorder-blocks") 24 %:pragma GCC optimize("-fschedule-insns") 25 %:pragma GCC optimize("inline-functions") 26 %:pragma GCC optimize("-ftree-tail-merge") 27 %:pragma GCC optimize("-fschedule-insns2") 28 %:pragma GCC optimize("-fstrict-aliasing") 29 %:pragma GCC optimize("-fstrict-overflow") 30 %:pragma GCC optimize("-falign-functions") 31 %:pragma GCC optimize("-fcse-skip-blocks") 32 %:pragma GCC optimize("-fcse-follow-jumps") 33 %:pragma GCC optimize("-fsched-interblock") 34 %:pragma GCC optimize("-fpartial-inlining") 35 %:pragma GCC optimize("no-stack-protector") 36 %:pragma GCC optimize("-freorder-functions") 37 %:pragma GCC optimize("-findirect-inlining") 38 %:pragma GCC optimize("-fhoist-adjacent-loads") 39 %:pragma GCC optimize("-frerun-cse-after-loop") 40 %:pragma GCC optimize("inline-small-functions") 41 %:pragma GCC optimize("-finline-small-functions") 42 %:pragma GCC optimize("-ftree-switch-conversion") 43 %:pragma GCC optimize("-foptimize-sibling-calls") 44 %:pragma GCC optimize("-fexpensive-optimizations") 45 %:pragma GCC optimize("-funsafe-loop-optimizations") 46 %:pragma GCC optimize("inline-functions-called-once") 47 %:pragma GCC optimize("-fdelete-null-pointer-checks") 48 49 #include <bits/stdc++.h> 50 using namespace std; 51 const int N = 1e5 + 10, p = 1e9 + 7; 52 typedef long long ll; 53 vector<int> g[N]; 54 int fa[N][21], dep[N], n, q; 55 56 ll pw(ll a, ll b) { 57 ll r = 1; 58 for( ; b ; b >>= 1, a = a * a % p) if(b & 1) r = r * a % p; 59 return r; 60 } 61 62 ll inv(ll a) { return pw(a, p - 2); } 63 64 ll f[N]; // 从u回到fa[u]的期望步数 65 66 ll h[N]; 67 68 void dfs(int u) { 69 dep[u] = dep[fa[u][0]] + 1; 70 for(int i = 0 ; i < g[u].size() ; ++ i) { 71 int v = g[u][i]; 72 if(v == fa[u][0]) continue; 73 fa[v][0] = u; 74 dfs(v); 75 } 76 for(int i = 0 ; i < g[u].size() ; ++ i) { 77 int v = g[u][i]; 78 if(v == fa[u][0]) continue; 79 f[u] = (f[u] + f[v] + 1) % p; 80 } 81 f[u] = (f[u] + 1) % p; 82 } 83 84 void dfs2(int u) { 85 int fa = :: fa[u][0], deg = g[fa].size(); 86 ll sum = 0; 87 for(int i = 0 ; i < g[u].size() ; ++ i) { 88 int v = g[u][i]; 89 if(v == fa) sum = (sum + h[u] + 1) % p; 90 else sum = (sum + f[v] + 1) % p; 91 } 92 for(int i = 0 ; i < g[u].size() ; ++ i) { 93 int v = g[u][i]; 94 if(v != fa) h[v] = (sum - f[v]) % p, dfs2(v); 95 } 96 } 97 98 void dfs3(int u) { 99 for(int i = 0 ; i < g[u].size() ; ++ i) { 100 int v = g[u][i]; 101 if(v == fa[u][0]) continue; 102 f[v] = (f[v] + f[u]) % p; 103 h[v] = (h[v] + h[u]) % p; 104 dfs3(v); 105 } 106 } 107 108 int getlca(int u, int v) { 109 if(dep[u] < dep[v]) swap(u, v); 110 for(int i = 20 ; ~ i ; -- i) if(dep[fa[u][i]] >= dep[v]) u = fa[u][i]; 111 if(u == v) return u; 112 for(int i = 20 ; ~ i ; -- i) if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; 113 return fa[u][0]; 114 } 115 116 ll sol(int u, int v) { 117 ll res = 0; 118 int d = getlca(u, v); 119 res += (f[u] - f[d]) % p; 120 res %= p; 121 res += (h[v] - h[d]) % p; 122 res %= p; 123 return (res % p + p) % p; 124 } 125 126 int main() { 127 freopen("tree.in", "r", stdin); 128 freopen("tree.out", "w", stdout); 129 scanf("%d%d", &n, &q); 130 for(int i = 1, u, v ; i < n ; ++ i) { 131 scanf("%d%d", &u, &v); 132 g[u].push_back(v), g[v].push_back(u); 133 } 134 dfs(1); 135 f[1] = h[1] = 0; 136 dfs2(1); 137 dfs3(1); 138 for(int j = 1 ; j <= 20 ; ++ j) 139 for(int i = 1 ; i <= n ; ++ i) 140 fa[i][j] = fa[fa[i][j - 1]][j - 1]; 141 for(int i = 1, u, v ; i <= q ; ++ i) { 142 scanf("%d%d", &u, &v); 143 printf("%lld\n", sol(u, v)); 144 } 145 }