标签:int fa depth maxn lca day dp
题目比较难读,因为n很小因此可以枚举哪一个点为根节点,计算每对逆序对的贡献(就是概率)
对于一个逆序对产生的贡献,可以看成较大节点先选中的概率,可以用dp预处理求出(u,v)到父节点p的概率
倍增求lca. https://codeforces.com/contest/1541/problem/D
挺难解释。。
倍增求lca 预处理o(n),每次查询o(logn)。
vector<int> mp[maxn];
int f[maxn][20], depth[maxn];
void dfs(int u, int fa)
{
depth[u] = depth[fa] + 1;
f[u][0] = fa;
for (int k = 1; k < 20; k++)
f[u][k] = f[f[u][k - 1]][k - 1];
for (auto v : mp[u]) {
if (v == fa)
continue;
dfs(v, u);
}
}
int lca(int u, int v)
{
if (depth[u] > depth[v])
swap(u, v);
int d = depth[v] - depth[u];
for (int i = 19; i >= 0; i--) {
if ((d >> i) & 1)
v = f[v][i];
}
if (u == v)
return u;
for (int i = 19; i >= 0; i--) {
if (f[u][i] != f[v][i])
u = f[u][i], v = f[v][i];
}
return f[u][0];
}
还有一个dp打表题: https://ac.nowcoder.com/acm/contest/18196/I
lkw orz!!
打表代码:
memset(dp, 0x3f, sizeof(dp));
dp[0] = 0;
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= i; j++) {
int len1 = j - 1;
int len2 = dp[i - j];
dp[i] = min(dp[i], max(len1, len2) + 1);
}
cout << i << " " << dp[i] << endl;
}
~i'm waking up~
标签:int,fa,depth,maxn,lca,day,dp 来源: https://www.cnblogs.com/lingdie/p/15017384.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。