Submission #1160927

#TimeUsernameProblemLanguageResultExecution timeMemory
1160927not_amir철인 이종 경기 (APIO18_duathlon)C++20
0 / 100
103 ms27328 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

struct ret {
    vector<ll> c = {};
    ll suma = 0, summ = 0;

    void expand(int val = 0) {
        summ += suma;
        suma += val;
        c.push_back(val);
    }

    ret(int val) {
        expand(val);
    }

    ll& operator[](int idx) {
        return c[c.size() - 1 - idx];
    }

    [[nodiscard]] int siz() {
        return c.size();
    }
};

ll combine(ret& tot, ret sml) {
    ll ans = 0;
    for (int i = 0; i < sml.siz(); i++) {
        ans -= tot.suma * sml[i];
        ans += tot.suma * sml[i] * i;
        ans += tot.summ * sml[i];
        tot[i] += sml[i];
    }
    tot.suma += sml.suma;
    tot.summ += sml.summ;
    return ans;
}


vector<int> depth, parent;
vector<bool> visited;
vector<vector<int>> child;

vector<pair<int, int>> lo;

void dfs1(int v, vector<vector<int>> &G, int d = 0) {
    visited[v] = true;
    depth[v] = d;
    for (int u : G[v]) {
        if (visited[u]) {
            if (u != parent[v])
                lo.push_back({u, v});
            continue;
        }
        child[v].push_back(u);
        parent[u] = v;
        dfs1(u, G, d + 1);
    }
}

ll ans = 0;

ret dfs2(int v, vector<ll> &w, vector<vector<int>> &G) {
    ret curr(w[v]);
    for (int u : G[v]) {
        ret sml = dfs2(u, w, G);
        sml.expand();
        if (sml.siz() > curr.siz())
            swap(sml, curr);
        ans += combine(curr, sml);
    }
    return curr;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    vector<vector<int>> G(n + 1);
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    visited.resize(n + 1);
    depth.resize(n + 1);
    parent.resize(n + 1);
    child.resize(n + 1);
    dfs1(1, G);
    vector<ll> w(n + 1, 1);
    for (auto [u, v] : lo) {
        if (depth[u] < depth[v])
            swap(u, v);
        vector<int> cchild;
        int amo = 1;
        int uprev = -1, vprev = -1;
        while (depth[u] > depth[v]) {
            for (int x : child[u])
                if (x != uprev)
                    cchild.push_back(x);
            amo++;
            uprev = u;
            u = parent[u];
        }
        while (u != v) {
            for (int x : child[u])
                if (x != uprev)
                    cchild.push_back(x);
            amo++;
            uprev = u;
            u = parent[u];
            for (int x : child[v])
                if (x != vprev)
                    cchild.push_back(x);
            amo++;
            vprev = v;
            v = parent[v];
        }
        vector<int> tmp = child[v];
        child[v] = cchild;
        for (int x : tmp)
            if (x != uprev && x != vprev)
                child[v].push_back(x);
        w[v] = amo;
    }
    dfs2(1, w, child);
    ans *= 2;
    ll sum1 = 0, sum2 = 0;
    for (int i = 1; i <= n; i++) {
        ans += sum1 * w[i] * (w[i] - 1);
        ans += sum2 * w[i];
        sum1 += w[i];
        sum2 += w[i] * (w[i] - 1);
        ans += w[i] * (w[i] - 1) * (w[i] - 2);
    }
    cout << ans << '\n';
}

/*
7 6
1 2
2 3
2 4
2 5
5 6
5 7
 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...