QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#283767 | #7677. Easy Diameter Problem | A_programmer | TL | 0ms | 0kb | C++14 | 3.6kb | 2023-12-15 13:38:49 | 2023-12-15 13:38:50 |
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const ll mod = 1e9 + 7;
int n, len, Mid;
int U[305], V[305], cnt[1205][305], dis[605][605];
ll dp[2][1205][305], fac[2005], C[2005][2005];
vector<pii> g[605];
void precalc(int x)
{
fac[0] = C[0][0] = 1;
for (int i = 1; i <= x; i++)
{
fac[i] = fac[i - 1] * i % mod;
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
}
}
ll Ch(int n, int m) { return C[n + m - 1][n - 1]; } //n个盒子,填m个数,可空
void calc(int u, int fu, int id)
{
for (pii tmp : g[u])
{
int v = tmp.first;
if (v == fu) continue;
dis[id][v] = dis[id][u] + 1;
calc(v, u, id);
}
}
void travel(int st, int u, int fu, int dep)
{
cnt[st][dep]++;
for (pii tmp : g[u])
{
int v = tmp.first;
if (v == fu) continue;
travel(st, v, u, dep + 1);
}
}
void init()
{
for (int i = 1; i <= 2 * n - 1; i++) calc(i, 0, i);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (dis[i][j] > len)
{
len = dis[i][j];
for (int k = 1; k < 2 * n; k++)
if (dis[i][j] == dis[i][k] + dis[k][j] && dis[i][k] == dis[k][j])
{
Mid = k;
break;
}
}
len >>= 1;
for (int i = 1; i <= n - 1; i++)
{
travel(4 * (i - 1), V[i], i + n, 0);
travel(4 * (i - 1) + 1, U[i], i + n, 0);
travel(4 * (i - 1) + 2, i + n, U[i], 0);
travel(4 * (i - 1) + 3, i + n, V[i], 0);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
freopen("tmp.in", "r", stdin);
cin >> n;
if (n == 1) return cout << "1", 0;
for (int i = 1; i < n; i++)
{
int u, v;
cin >> U[i] >> V[i], u = U[i], v = V[i];
g[v].emplace_back(make_pair(i + n, 4 * (i - 1)));
g[u].emplace_back(make_pair(i + n, 4 * (i - 1) + 1));
g[i + n].emplace_back(make_pair(u, 4 * (i - 1) + 2));
g[i + n].emplace_back(make_pair(v, 4 * (i - 1) + 3));
}
precalc(2000);
init();
int p = 0;
for (pii tmp : g[Mid]) dp[p][tmp.second][cnt[tmp.second][len]] = fac[cnt[tmp.second][len]];
for (int r = len - 1; r; r--, p ^= 1)
{
memset(dp[p ^ 1], 0, sizeof(dp[p ^ 1]));
for (int st = 0; st < 4 * (n - 1); st++)
{
int id = st / 4 + 1, ls, nw, op;
if (st % 4 == 0) nw = id + n, ls = V[id], op = 0;
else if (st % 4 == 1) nw = id + n, ls = U[id], op = 0;
else if (st % 4 == 2) nw = U[id], ls = id + n, op = 1;
else nw = V[id], ls = id + n, op = 1;
int nst = st ^ 3;
for (int l = 1; l <= n; l++)
{
if (!dp[p][st][l]) continue;
//转移1:反复横跳。此时枚举删去点数m作为新的可插入长度,剩下的直接插入前面即可。
//组合数:(cnt排列) * (cnt-m个插入l)
for (int m = 1; m <= cnt[nst][r]; m++)
(dp[p ^ 1][nst][m] += dp[p][st][l] * Ch(l, cnt[nst][r] - m) % mod * fac[cnt[nst][r]] % mod) %= mod;
//转移2:继续向前。此时之前的点数直接并入l,作为新的可插入长度。
//组合数:(u点数排列) * (去u去v点数排列) * (去u去v点数插入l+1)
for (pii tmp : g[nw])
{
int v = tmp.first;
if (v == ls || !cnt[tmp.second ^ 3][r - 1]) continue;
int t1 = cnt[st][r - 1];
int t2 = cnt[tmp.second][r] - cnt[st][r - 1];
if (l + t1 + t2 > n) continue;
(dp[p ^ 1][tmp.second][l + t1 + t2] += dp[p][st][l] * fac[t1] % mod * fac[t2] % mod * Ch(l + t1 + 1, t2) % mod) %= mod;
}
}
}
}
ll ans = 0;
for (int st = 0; st < 4 * (n - 1); st++)
{
if ((st % 4) < 2) continue;
for (int i = 1; i <= n; i++) (ans += dp[p][st][i]) %= mod;
}
cout << ans;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
3 1 2 3 2