day-3

题目比较难读,因为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~

上一篇:如何查看全局安装的包


下一篇:repo 常用操作总结-实战宝典