# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
542762 | chonka | Making Friends on Joitter is Fun (JOI20_joitter2) | C++98 | 26 ms | 56704 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std ;
#define MAXN 300007
int n , m ;
pair < int , int > a[ MAXN ] ;
set < int > v[ MAXN ] ;
map < int , int > entering[ MAXN ] ;
map < int , int > leaving[ MAXN ] ;
set < int > all_entering[ MAXN ] ;
int sm_entering[ MAXN ] ;
int prv[ MAXN ] ;
int cnt[ MAXN ] , sz[ MAXN ] ;
long long ans = 0 ;
int get ( int x ) {
if ( prv[ x ] == -1 ) { return x ; }
int y = get ( prv[ x ] ) ;
prv[ x ] = y ;
return y ;
}
void unite ( int x , int y ) {
int k1 = get ( x ) ;
int k2 = get ( y ) ;
if ( k1 != k2 ) {
ans -= 1LL * sz[ k1 ] * ( sz[ k1 ] - 1 ) ;
ans -= 1LL * sz[ k1 ] * sm_entering[ k1 ] ;
ans -= 1LL * sz[ k2 ] * ( sz[ k2 ] - 1 ) ;
ans -= 1LL * sz[ k2 ] * sm_entering[ k2 ] ;
if ( sz[ k1 ] >= sz[ k2 ] ) {
for ( auto [ aux , cnt ] : entering[ k2 ] ) {
leaving[ aux ][ k2 ] -= cnt ;
if ( aux != k1 ) {
sm_entering[ k1 ] += cnt ;
entering[ k1 ][ aux ] += cnt ;
leaving[ aux ][ k1 ] += cnt ;
}
}
for ( auto [ aux , cnt ] : leaving[ k2 ] ) {
entering[ aux ][ k2 ] -= cnt ;
sm_entering[ aux ] -= cnt ;
if ( aux != k1 ) {
sm_entering[ aux ] += cnt ;
entering[ aux ][ k1 ] += cnt ;
leaving[ k1 ][ aux ] += cnt ;
}
}
for ( auto aux : all_entering[ k2 ] ) {
all_entering[ k1 ].insert ( aux ) ;
}
prv[ k2 ] = k1 ;
sz[ k1 ] += sz[ k2 ] ;
ans += 1LL * sz[ k1 ] * ( sz[ k1 ] - 1 ) ;
ans += 1LL * sz[ k1 ] * sm_entering[ k1 ] ;
}
else {
for ( auto [ aux , cnt ] : entering[ k1 ] ) {
leaving[ aux ][ k1 ] -= cnt ;
if ( aux != k2 ) {
sm_entering[ k2 ] += cnt ;
entering[ k2 ][ aux ] += cnt ;
leaving[ aux ][ k2 ] += cnt ;
}
}
for ( auto [ aux , cnt ] : leaving[ k1 ] ) {
entering[ aux ][ k1 ] -= cnt ;
sm_entering[ aux ] -= cnt ;
if ( aux != k2 ) {
sm_entering[ aux ] += cnt ;
entering[ aux ][ k2 ] += cnt ;
leaving[ k2 ][ aux ] += cnt ;
}
}
for ( auto aux : all_entering[ k1 ] ) {
all_entering[ k2 ].insert ( aux ) ;
}
prv[ k1 ] = k2 ;
sz[ k2 ] += sz[ k1 ] ;
ans += 1LL * sz[ k2 ] * ( sz[ k2 ] - 1 ) ;
ans += 1LL * sz[ k2 ] * sm_entering[ k2 ] ;
}
}
}
void input ( ) {
cin >> n >> m ;
for ( int i = 1 ; i <= m ; ++ i ) {
cin >> a[ i ].first >> a[ i ].second ;
}
}
void solve ( ) {
for ( int i = 1 ; i <= n ; ++ i ) {
prv[ i ] = -1 , sz[ i ] = 1 ;
}
for ( int i = 1 ; i <= m ; ++ i ) {
int x = a[ i ].first , y = a[ i ].second ;
if ( get ( x ) != get ( y ) ) {
if ( leaving[ get ( y ) ].find ( get ( x ) ) != leaving[ get ( y ) ].end ( ) ) {
unite ( x , y ) ;
}
else {
if ( all_entering[ get ( y ) ].find ( x ) == all_entering[ get ( y ) ].end ( ) ) {
ans += sz[ y ] ;
++ leaving[ get ( x ) ][ get ( y ) ] ;
++ entering[ get ( y ) ][ get ( x ) ] ;
++ sm_entering[ get ( y ) ] ;
all_entering[ get ( y ) ].insert ( x ) ;
}
}
}
cout << ans << "\n" ;
}
}
int main ( ) {
ios_base :: sync_with_stdio ( false ) ;
cin.tie ( NULL ) ;
int t = 1 ;
// cin >> t ;
while ( t -- ) {
input ( ) ;
solve ( ) ;
}
return 0 ;
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |