真是充实的一天啊,赞美数论!
基本没有自己想出来的,所以没什么好说
题解其实也没有特别想明白,只能是先照着敲出来。想到这辈子可能都学不会数论了,心情莫名沉重
然后闲着无聊,尝试改变自己的码风(咱就是说,代码不打空格的都是邪教!/bx/bx)。真的感觉轻松了不少
我不能再说了
因为代码已经等不及了
#include
#define rep(i, j, k) for(ll i = (j), _i = (k); i = _i; i--)
#define ll long long
#define Nx 205
using namespace std;
//-------------------------------------//
ll read() {
ll x = 0, f = 0; char ch;
while(!isdigit(ch = getchar())) f |= ch == '-';
while(isdigit(ch)) x = (x<<3) + (x<>1) % mod : 1ll; }
class TreeChainPartition {
private :
ll son[Nx], siz[Nx], f[Nx], top[Nx];
protected :
ll dfs1(ll u, ll fa) {
dep[u] = dep[fa] + 1, f[u] = fa;
for(auto v : G[u])
if(v != fa) {
siz[u] += dfs1(v, u);
if(siz[v] > siz[son[u]]) son[u] = v;
}
return siz[u] + 1;
}
void dfs2(ll u, ll fa, ll ffa) {
top[u] = ffa;
if(son[u]) dfs2(son[u], u, ffa);
for(auto v : G[u]) if(v != fa && v != son[u])
dfs2(v, u, v);
}
ll LCA(ll u, ll v) {
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
u = f[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
void init() {
memset(siz, 0, sizeof siz);
memset(son, 0, sizeof son);
}
} ;
class SuddenlyArise : public TreeChainPartition {
public :
void main(ll rt) {
init();
dfs1(rt, 0), dfs2(rt, 0, rt);
rep(i, 1, n)
rep(j, 1, i - 1) {
ll t = LCA(i, j);
ans = (ans + dp[dep[i] - dep[t]][dep[j] - dep[t]]) % mod;
}
return /*^_^*/void();
}
} Run;
int main()
{
rep(i, 1, (n = read()) - 1) {
ll u = read(), v = read();
G[u].push_back(v), G[v].push_back(u);
}
rep(i, 1, n) dp[0][i] = 1;
rep(i, 1, n) rep(j, 1, n) dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) * inv2 % mod;
rep(i, 1, n) Run.main(i);
printf("%lld", ans * ksm(n, mod - 2) % mod);
return 0;
}
( the solution to "Tree Array" )