제출 #1106829

#제출 시각아이디문제언어결과실행 시간메모리
1106829mispertion철인 이종 경기 (APIO18_duathlon)C++17
100 / 100
384 ms85228 KiB
#include<bits/stdc++.h>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
using ll = long long;
#define int ll
using ld = long double;
using pii = pair<int, int>;
#define F first
#define S second

const ld PI = 3.1415926535;
const int N = 5e5 + 2;
const int M = 2e6 + 1;
int mod = 998244353;
const int infi = INT_MAX;
const ll infl = LLONG_MAX;

int mult(int a, int b) {
    return a * 1LL * b % mod;
}

int sum(int a, int b) {
    if (a + b < 0)
        return a + b + mod;
    if (a + b >= mod)
        return a + b - mod;
    return a + b;
}


ll binpow(ll a, ll n) {
    if (n == 0)
        return 1;
    if (n % 2 == 1) {
        return binpow(a, n - 1) * a % mod;
    } else {
        ll b = binpow(a, n / 2);
        return b * b % mod;
    }
}

int n, m, tin[N], used[N], low[N], cnt[N], cur, tick, art[N], sz[N], dp[N], ndp[N];
vector<int> g[N];
vector<int> ng[N];

void dfs(int v, int p){
    tin[v] = ++tick;
    low[v] = tin[v];
    used[v] = 1;
    int ch = 0;
    bool isart = false;
    for(auto u : g[v]){
        if(u == p) continue;
        if(used[u]){
            low[v] = min(low[v], tin[u]);
        }else{
            dfs(u, v);
            low[v] = min(low[v], low[u]);
            ch++;
            if(p != 0 && low[u] >= tin[v])
                isart = true;
        }
    }
    if(p == 0 && ch > 1)
        isart = true;
    if(isart)
        art[v] = 1;
}

map<pii, int> mp;

void dfs1(int v, int c){
    used[v] = 1;
    if(c == 0){
        for(auto u : g[v]){
            if(used[u]) continue;
            cur++;
            mp[{u, v}] = cur;
            mp[{v, u}] = cur;
            dfs1(u, cur);
        }
        return;
    }
    for(auto u : g[v]){
        if(used[u]){
            if(tin[u] < tin[v]){
                mp[{u, v}] = c;
                mp[{v, u}] = c;
            }
            continue;
        }
        if(low[u] >= tin[v]){
            cur++;
            mp[{u, v}] = cur;
            mp[{v, u}] = cur;
            dfs1(u, cur);
        }else{
            mp[{u, v}] = c;
            mp[{v, u}] = c;
            dfs1(u, c);
        }
    }
}

void dfs2(int v, int p){
    used[v] = 1;
    if(v <= n){
        sz[v] = 1;
    }else{
        dp[v] = cnt[v - n] * (cnt[v - n] - 1);
        sz[v] = cnt[v - n];
    }
    int cur = 0;
    for(auto u : ng[v]){
        if(u == p) continue;
        dfs2(u, v);
        sz[v] += sz[u];
        if(v > n){
            dp[v] += 2 * cnt[v - n] * sz[u];
            dp[v] += 2 * cur * sz[u];
            cur += sz[u];
        }
    }
}

void dfs3(int v, int p, int wh){
    used[v] = 1;
    if(v > n){
        int csm = (cnt[v - n]) * (cnt[v - n] - 1) / 2 + (wh - sz[v]) * (cnt[v - n]);
        int cs = wh - sz[v];
        for(auto u : ng[v]){
            if(u == p) continue;
            csm += (sz[u] * cnt[v - n]);
            csm += (cs * sz[u]);
            cs += sz[u];
        }
        for(auto u : ng[v]){
            if(u == p) continue;
            csm -= (sz[u] * cnt[v - n]);
            csm -= (sz[u] * (cs - sz[u]));
            ndp[u] = csm * 2;
            csm += (sz[u] * cnt[v - n]);
            csm += (sz[u] * (cs - sz[u]));
            dfs3(u, v, wh);
        }
    }else{
        for(auto u : ng[v]){
            if(u != p)
                dfs3(u, v, wh);
        }
    }
}

int ans = 0;
void dfs4(int v, int p, int wh){
    used[v] = 1;
    if(v <= n){
        ans += ndp[v];
        int cs = wh - sz[v];
        for(auto u : ng[v]){
            if(u == p) continue;
            ans += dp[u];
            ans += 2 * sz[u] * cs;
            cs += sz[u];
        }
    }else{
        ans += cnt[v - n] * (cnt[v - n] - 1) * (cnt[v - n] - 2);
        int cs = wh - sz[v];
        ans += 2 * (cnt[v - n] * (cnt[v - n] - 1) * (wh - sz[v]));
        for(auto u : ng[v]){
            if(u == p) continue;
            ans += 2 * (cnt[v - n] * (cnt[v - n] - 1) * sz[u]);
            ans += (cnt[v - n] * (2 * (cs * sz[u])));
            cs += sz[u];
        }
    }
    for(auto u : ng[v]){
        if(u == p) continue;
        dfs4(u, v, wh);
    }
}

void solve() {
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        int u, v;
        cin >> u >> v;
        g[v].push_back(u);
        g[u].push_back(v);
    }
    for(int i = 1; i <= n; i++){
        if(!used[i])
            dfs(i, 0);
    }
    for(int i = 1; i <= n; i++)
        used[i] = 0;
    for(int i = 1; i <= n; i++)
        if(!used[i])
            dfs1(i, 0);
    for(int i = 1; i <= n; i++){
        if(art[i]){
            for(auto e : g[i]){
                ng[i].push_back(n + mp[{i, e}]);
                ng[n + mp[{i, e}]].push_back(i);
            }
            sort(ng[i].begin(), ng[i].end());
            ng[i].resize(unique(ng[i].begin(), ng[i].end()) - ng[i].begin());
        }else{
            if(g[i].size() > 0){
                cnt[mp[{g[i][0], i}]]++;
            }
        }
    }
    for(int i = n + 1; i <= n + cur; i++){
        ng[i].resize(unique(ng[i].begin(), ng[i].end()) - ng[i].begin());
    }
    for(int i = n + 1; i <= n + cur; i++){
        if(!used[i])
            dfs2(i, 0);
    }
    for(int i = 1; i <= n + cur; i++)
        used[i] = 0;
    for(int i = n + 1; i <= n + cur; i++){
        if(!used[i])
            dfs3(i, 0, sz[i]);
    }
    for(int i = 1; i <= n + cur; i++)
        used[i] = 0;
    for(int i = n + 1; i <= n + cur; i++){
        if(!used[i])
            dfs4(i, 0, sz[i]);
    }
    for(int i = 1; i <= n + cur; i++)
        used[i] = 0;
    cout << ans << '\n';
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int t = 1;
    //cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
#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...