제출 #1162289

#제출 시각아이디문제언어결과실행 시간메모리
1162289spycoderyt조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++20
17 / 100
518 ms92420 KiB
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+5;
set<int> child[N];
int sz[N],p[N],ans=0;
set<int> graph[N],rgraph[N];
queue<pair<int,int> > to_merge;
void add_weak(int a,int b) {
    graph[a].insert(b);
    rgraph[b].insert(a);
    if(graph[b].count(a)) to_merge.push({a,b});
}
int fp(int u) {
    if(p[u] == u)return u;
    else return fp(p[u]);
}
int fsz(int u) {return graph[u].size() + rgraph[u].size() + child[u].size();}
void onion(int a,int b) {
    if(a==b)return;
    if(fsz(a) < fsz(b))swap(a,b);
    ans+=sz[a] * child[b].size() + sz[b] * child[a].size();
    p[b] = a;
    sz[a]+=sz[b];
    for(auto e : child[b]) {
        if(child[a].count(e))ans-=sz[a];
        else child[a].insert(e);
    }
    graph[a].erase(b);
    rgraph[a].erase(b);
    graph[b].erase(a);
    rgraph[b].erase(a);
    for(auto e : graph[b]) {
        rgraph[e].erase(b);
        add_weak(a,e);
    }
    for(auto e : rgraph[b]){
        graph[b].erase(e);
        add_weak(e,a);
    }
}

int main() {
    int a,b,n,m;
    cin>>n>>m;
    for(int i = 1;i<=n;i++) {
        p[i]=i;
        sz[i]=1;
        child[i].insert(i);
    }
    for(int i = 0;i<m;i++) {
        cin>>a>>b;
        b = fp(b);
        if(fp(a)!=b&&!child[b].count(a)){
            child[b].insert(a);
            ans+=sz[b];
            a=fp(a);
            add_weak(a,b);
            while(to_merge.size()) {
                auto [a,b] = to_merge.front();
                to_merge.pop();
                onion(fp(a),fp(b));
            }
        }
        cout<<ans<<"\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...