#include <bits/stdc++.h>
#define pb push_back
#define rbg(v) v.rbegin()
#define bg(v) v.begin()
#define all(v) bg(v), v.end()
#define sz(v) int(v.size())
#define mp make_pair
#define fi first
#define se second
#define forn(i, a, b) for(int i = int(a); i <= int(b); ++ i)
#define for0(i, n) forn(i, 0, n - 1)
#define for1(i, n) forn(i, 1, n)
#define fora(i, a, b) for(int i = int(a); i >= int(b); -- i)
#define far0(i, n) fora(i, n - 1, 0)
#define far1(i, n) fora(i, n, 1)
#define foru(i, v) for(auto & i : v)
#define lb lower_bound
#define ub upper_bound
#define sz(v) int(v.size())
#define ord1(s, n) s + 1, s + int(n) + 1
#define ord0(s, n) s, s + int(n)
#define debug(x) /// cout << #x << " = " << x << endl
using namespace std;
///#include <bits/extc++.h>
///using namespace __gnu_pbds;
///typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ost;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef vector<ll> vl;
typedef vector<pii> vii;
typedef long double ld;
typedef double db;
typedef long long lli;
///typedef __int128 Int;
const int mod1 = 1e9 + 7;
const int mod2 = 998244353;
///const int inf = 1e4
const int MX = 1e5 + 2;
struct SML{
map<int, int> in;
map<int, int> out;
set<int> in2;
int sum_in;
SML () {
sum_in = 0;
}
};
SML * comp[MX];
int p[MX], setSize[MX];
ll ori_edg, com_gra, adi_edg;
queue<pii> q;
void UnionFind(int N){
for1(i, N) p[i] = i, setSize[i] = 1;
}
int findSet(int i){
return (p[i] == i) ? i : (p[i] = findSet(p[i]));
}
bool isSameSet(int i, int j){
return findSet(i) == findSet(j);
}
void unionSet(int i, int j){
if(isSameSet(i, j)) return;
int x = findSet(i), y = findSet(j);
if(comp[x]->in.size() + comp[x]->out.size() > comp[y]->in.size() + comp[y]->out.size()) swap(x, y);
adi_edg -= ll(comp[y]->sum_in) * ll(setSize[y] - 1);
adi_edg -= ll(comp[x]->sum_in) * ll(setSize[x] - 1);
com_gra -= ll(setSize[x]) * ll(setSize[x] - 1);
com_gra -= ll(setSize[y]) * ll(setSize[y] - 1);
comp[y]->sum_in += comp[x]->sum_in;
for(auto [key, val] : comp[x]->in){
if(key == x) continue;
if(key == y){
ori_edg -= val;
comp[y]->sum_in -= val;
continue;
}
comp[key]->out.erase(x);
comp[key]->out[y] += val;
if(comp[y]->out.count(key))
q.push(mp(y, key));
comp[y]->in[key] += val;
}
for(auto [key, val] : comp[x]->out){
if(key == x) continue;
if(key == y){
ori_edg -= val;
comp[y]->sum_in -= val;
continue;
}
comp[key]->in.erase(x);
comp[key]->in[y] += val;
if(comp[y]->in.count(key))
q.push(mp(y, key));
comp[y]->out[key] += val;
}
for(auto val : comp[x]->in2) comp[y]->in2.insert(val);
p[x] = y;
setSize[y] += setSize[x];
com_gra += ll(setSize[y]) * ll(setSize[y] - 1);
adi_edg += ll(comp[y]->sum_in) * ll(setSize[y] - 1);
}
void answer(){
cout << ori_edg + adi_edg + com_gra << '\n';
}
void solve(){
int n, m;
cin >> n >> m;
for1(i, n) comp[i] = new SML();
UnionFind(n);
while(m --){
int u, v;
cin >> u >> v;
if(isSameSet(u, v)){
answer();
continue;
}
int x, y;
x = findSet(u), y = findSet(v);
if(!comp[x]->in.count(y)){
if(comp[y]->in2.count(u)){
answer();
continue;
}
ori_edg ++;
adi_edg += ll(setSize[y] - 1);
comp[y]->sum_in ++;
comp[y]->in[x] ++;
comp[x]->out[y] ++;
comp[y]->in2.insert(u);
answer();
continue;
}
unionSet(u, v);
while(!q.empty()){
unionSet(q.front().fi, q.front().se);
q.pop();
}
answer();
}
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t = 1;
///cin >> t;
for1(i, t){
///cout << "Case #" << i << ": ";
solve();
///cout << '\n';
}
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
0 ms |
348 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
0 ms |
348 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Incorrect |
0 ms |
348 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |