답안 #384165

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
384165 2021-03-31T15:40:49 Z VodkaInTheJar 조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2) C++14
0 / 100
9 ms 12284 KB
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define endl '\n'

using namespace std;

const int maxn = 1e5 + 3; 

int n, m; 
void read()
{
	cin >> n >> m; 
}

int par[maxn], sz[maxn];
set <int> adj[maxn], rev_adj[maxn];
vector <int> members[maxn];

int find_root(int ver)
{
    if (ver == par[ver])
        return ver;

    return par[ver] = find_root(par[ver]);
}

long long ans = 0; 
vector <pair <int, int> > to_add;
void merge(int a, int b)
{
    a = find_root(a), b = find_root(b);
    

    if (a == b || adj[a].find(b) == adj[a].end() || adj[b].find(a) == adj[b].end())
        return;

    ans -= 1ll * sz[a] * (sz[a] - 1);
    ans -= 1ll * sz[b] * (sz[b] - 1);
    ans -= 1ll * (int)rev_adj[a].size() * sz[a];
    ans -= 1ll * (int)rev_adj[b].size() * sz[b];

    if (sz[a] < sz[b])
        swap(a, b);

    for (auto i: members[b])
        members[a].push_back(i);

    for (auto j: adj[b])
        if (j != a)
        {
            adj[a].insert(j);
            if (adj[j].find(a) != adj[j].end())
                to_add.push_back({a, j});
        }

    for (auto j: rev_adj[b])
    {
        if (find_root(j) == a)
            continue;

        if (adj[a].find(j) != adj[a].end())
            to_add.push_back({j, a});

        adj[find_root(j)].erase(b);
        adj[find_root(j)].insert(a);
        rev_adj[a].insert(j);
    }
    
    adj[a].erase(b);
    vector <int> to_remove;
    for (auto i: members[b])
        if (rev_adj[a].find(i) != rev_adj[a].end())
            rev_adj[a].erase(i);

    par[b] = a;
    sz[a] += sz[b];
    ans += 1ll * sz[a] * (sz[a] - 1);
    ans += 1ll * (int)rev_adj[a].size() * sz[a];
}

pair <int, int> e[maxn * 3];
void solve()
{
    for (int i = 1; i <= n; i++)
    {
        par[i] = i, sz[i] = 1; 
        members[i].push_back(i);
    }

    for (int i = 1; i <= m; i++)
    {
        cin >> e[i].first >> e[i].second;
        
        int a = find_root(e[i].first), b = find_root(e[i].second);
        if (a != b)
        {
            ans -= 1ll * (int)rev_adj[b].size() * sz[b]; 
            adj[a].insert(b);
            rev_adj[b].insert(e[i].first);

            ans += 1ll * (int)rev_adj[b].size() * sz[b];

            if (adj[b].find(a) != adj[b].end())
            {
                to_add.push_back({a, b});
                while (!to_add.empty())
                {
                    auto curr = to_add.back();
                    to_add.pop_back();

                    merge(curr.first, curr.second);
                }
            }
        }

       cout << ans << endl; 
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	
	read();
	solve();
}
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 12140 KB Output is correct
2 Correct 9 ms 12140 KB Output is correct
3 Correct 9 ms 12140 KB Output is correct
4 Correct 8 ms 12140 KB Output is correct
5 Correct 8 ms 12140 KB Output is correct
6 Correct 8 ms 12140 KB Output is correct
7 Incorrect 9 ms 12284 KB Output isn't correct
8 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 12140 KB Output is correct
2 Correct 9 ms 12140 KB Output is correct
3 Correct 9 ms 12140 KB Output is correct
4 Correct 8 ms 12140 KB Output is correct
5 Correct 8 ms 12140 KB Output is correct
6 Correct 8 ms 12140 KB Output is correct
7 Incorrect 9 ms 12284 KB Output isn't correct
8 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 12140 KB Output is correct
2 Correct 9 ms 12140 KB Output is correct
3 Correct 9 ms 12140 KB Output is correct
4 Correct 8 ms 12140 KB Output is correct
5 Correct 8 ms 12140 KB Output is correct
6 Correct 8 ms 12140 KB Output is correct
7 Incorrect 9 ms 12284 KB Output isn't correct
8 Halted 0 ms 0 KB -