Submission #946770

#TimeUsernameProblemLanguageResultExecution timeMemory
946770phoenix0423Making Friends on Joitter is Fun (JOI20_joitter2)C++17
100 / 100
1187 ms117052 KiB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
#define fastio ios::sync_with_stdio(false), cin.tie(0)
#define pb push_back
#define eb emplace_back
#define f first
#define s second
#define int long long 
const int maxn = 2e5 + 5;
set<int> st[maxn], in[maxn], out[maxn], sgin[maxn], sgout[maxn];
int sz[maxn];
int par[maxn];
int root(int x){ return x == par[x] ? x : par[x] = root(par[x]);}
int cur = 0;
queue<pll> q;

void merge(int a, int b){
    int fa = root(a), fb = root(b);
    if(fa == fb) return;
    if(out[fb].find(fa) == out[fb].end()){
        if(sgin[fb].find(a) == sgin[fb].end()){
            cur += st[fb].size();
            sgin[fb].insert(a), sgout[a].insert(fb);
            in[fb].insert(fa), out[fa].insert(fb);
        }
        return;
    }
    cur -= 1LL * st[fa].size() * (st[fa].size() - 1);
    cur -= 1LL * st[fb].size() * (st[fb].size() - 1);
    in[fa].erase(fb), out[fb].erase(fa);
    if(st[fa].size() > st[fb].size()) swap(fa, fb);
    for(auto x : st[fa]){
        for(auto y : sgout[x]){
            cur -= st[y].size();
            sgin[y].erase(x);
            q.push({x, y});
        }
        sgout[x].clear();
    }
    for(auto x : sgin[fa]){
        cur -= st[fa].size();
        sgout[x].erase(fa);
        q.push({x, fa});
    }
    sgin[fa].clear();
    for(auto x : out[fa]) in[x].erase(fa);
    for(auto x : in[fa]) out[x].erase(fa);
    for(auto x : st[fa]) st[fb].insert(x);
    par[fa] = fb;
    cur += 1LL * st[fb].size() * (st[fb].size() - 1);
    cur += 1LL * sgin[fb].size() * st[fa].size();
    st[fa].clear();
}

signed main(void){
    fastio;
    int n, m;
    cin>>n>>m;
    for(int i = 0; i < n; i++) par[i] = i;
    for(int i = 0; i < n; i++) st[i].insert(i);
    for(int i = 0; i < m; i++){
        int a, b;
        cin>>a>>b;
        a--, b--;
        q.push({a, b});
        while(!q.empty()){
            auto [a, b] = q.front(); q.pop();
            merge(a, b);
        }
        cout<<cur<<"\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...