제출 #1123257

#제출 시각아이디문제언어결과실행 시간메모리
1123257I_FloPPed21조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++20
100 / 100
800 ms65348 KiB
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+2;
int n,m;
set<int> graph[N],rgraph[N],child[N];
int comp[N];
int size_comp[N];
int find(int point)
{
    //cout<<point<<" "<<comp[point]<<'\n';
    if(comp[point]==point)
    {
        return point;
    }
    else
    {
        int t=find(comp[point]);
        comp[point]=t;
        return t;
    }
}
long long ans=0;
vector<pair<int,int>> to_merge;
void merge_weak(int a,int b)
{
    graph[a].insert(b);
    rgraph[b].insert(a);

    if(graph[b].count(a))
        to_merge.push_back({a,b});
}
int dsu_size(int a)
{
    return graph[a].size()+rgraph[a].size()+child[a].size();
}
void uneste(int a,int b)
{
    if(find(a)==find(b))
        return;
    if(dsu_size(a)<dsu_size(b))
        swap(a,b);
    ans+=size_comp[a]*child[b].size()+size_comp[b]*child[a].size();
    size_comp[a]+=size_comp[b];
    comp[b]=a;
    for(auto u:child[b])
        {
            if(child[a].count(u))
                ans-=size_comp[a];
            else
                child[a].insert(u);
        }

    graph[a].erase(b);
    rgraph[a].erase(b);
    graph[b].erase(a);
    rgraph[b].erase(a);
    for(auto u:graph[b])
    {
        rgraph[u].erase(b);
        merge_weak(a,u);
    }
    for(auto u:rgraph[b])
    {
        graph[u].erase(b);
        merge_weak(u,a);
    }
}
void citeste()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        size_comp[i]=1;

        comp[i]=i;
        child[i].insert(i);
    }
    for(int i=1;i<=m;i++)
    {
        int a,b;
        cin>>a>>b;
        int top=find(b);
        if(find(a)!=find(b)&&child[top].find(a)==child[top].end())
        {
            child[top].insert(a);
            ans+=size_comp[top];
            int top2=find(a);
            merge_weak(top2,top);
            while(to_merge.empty()==false)
            {
                int x,y;
                tie(x,y)=to_merge.back();
                to_merge.pop_back();
                uneste(find(x),find(y));
            }
        }
        cout<<ans<<'\n';
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    citeste();
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...