QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#105357#6127. Kawa ExamSorting#WA 3ms17592kbC++206.8kb2023-05-13 23:03:462023-05-13 23:03:50

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-13 23:03:50]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:17592kb
  • [2023-05-13 23:03:46]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef unsigned long long ull ;
typedef pair < int , int > pii ;
typedef vector<int> vi;
#define fi first
#define se second
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

const int MAXN = 3e5 + 7 ;

int n , m ;
int a[ MAXN ] ;
vector < pii > gr[ MAXN ] ;
vector < int > v[ MAXN ] ;

int tp ;
int num[ MAXN ] ;
vector < int > st ;
int comp[ MAXN ] , cnt_comps ;
bool bridge[ MAXN ] ;
int ans[ MAXN ] ;
bool seen[ MAXN ] ;
int rv[ MAXN ] ;

int st_val ;
vector < int > all_comp ;

int dfs ( int at , int par ) {
    all_comp.push_back ( at ) ;
    int me = num[ at ] = ++ tp , e , y , top = me ;
    for ( auto pa : gr[ at ] ) if ( pa.se != par ) {
            tie ( y , e ) = pa ;
            if ( num[ y ] ) {
                top = min ( top , num[ y ] ) ;
                if ( num[ y ] < me ) {
                    st.push_back ( e ) ;
                }
            }
            else {
                int si = st.size ( ) ;
                int up = dfs ( y , e ) ;
                top = min ( top , up ) ;
                if ( up == me ) {
                    st.push_back ( e ) ;
                    int tot = st.size ( ) ;
                    ++ cnt_comps ;
                    for ( int i = si ; i < tot ; ++ i ) {
                        comp[ st[ i ] ] = cnt_comps ;
                    }
                    st.resize ( si ) ;
                }
                else if ( up < me ) { st.push_back ( e ) ; }
                else {
                    comp[ e ] = ++ cnt_comps ;
                    rv[ cnt_comps ] = e ;
                    bridge[ e ] = true ;
                }
            }
        }
    return top ;
}

int sub[ 2 ][ MAXN ] ;
set < pii > freqs[ 2 ] ;

void add ( int id , int x , int coef ) {
    if ( sub[ id ][ x ] != 0 ) { 
        freqs[ id ].erase ( { sub[ id ][ x ] , x } ) ;
    }
    sub[ id ][ x ] += coef ;
    if ( sub[ id ][ x ] != 0 ) { 
        freqs[ id ].insert ( { sub[ id ][ x ] , x } ) ;
    }
}

int get_mx ( int id ) {
    if ( freqs[ id ].empty ( ) == true ) { return 0 ; }
    auto it = freqs[ id ].rbegin ( ) ;
    return it->fi ;
}

int subtree[ MAXN ] ;
int heavy[ MAXN ] ;
bool cannot[ MAXN ] ;

void init_subtrees ( int x , int prv ) {
    // printf ( "-- %d %d\n" , x , prv ) ;
    subtree[ x ] = 0 ;
    if ( x <= n ) { subtree[ x ] = 1 ; }
    heavy[ x ] = 0 ;
    int mx = -1 ;
    for ( auto y : v[ x ] ) {
        if ( y == prv ) { continue ; }
        init_subtrees ( y , x ) ;
        subtree[ x ] += subtree[ y ] ;
        if ( mx < subtree[ y ] ) {
            mx = subtree[ y ] ;
            heavy[ x ] = y ;
        }
    }
}

void add_up ( int x , int prv , int coef ) {
    if ( x <= n ) {
        // printf ( " %d with %d\n" , x , coef ) ;
        add ( 0 , a[ x ] , coef ) ;
        add ( 1 , a[ x ] , -coef ) ;
    }
    for ( auto y : v[ x ] ) {
        if ( y == prv ) { continue ; }
        add_up ( y , x , coef ) ;
    }
}

void calc ( int x , int prv , bool fl ) {
    // printf ( "--- %d %d\n" , x , heavy[ x ] ) ;
    subtree[ x ] = 0 ;
    for ( auto y : v[ x ] ) {
        if ( y == prv || y == heavy[ x ] ) { continue ; }
        calc ( y , x , false ) ;
    }
    if ( heavy[ x ] != 0 ) { 
        calc ( heavy[ x ] , x , true ) ;
    }
    for ( auto y : v[ x ] ) {
        if ( y == prv || y == heavy[ x ] ) { continue ; }
        add_up ( y , x , 1 ) ;
    }
    if ( x <= n ) {
        // printf ( " %d with %d\n" , x , 1 ) ;
        add ( 0 , a[ x ] , 1 ) ;
        add ( 1 , a[ x ] , -1 ) ;
    }
    if ( x > n && bridge[ rv[ x - n ] ] == true && cannot[ rv[ x - n ] ] == false ) {
        // printf ( "edge %d adding %d + %d instead of %d\n" , x - n , get_mx ( 0 ) , get_mx ( 1 ) , st_val ) ;
        ans[ rv[ x - n ] ] += -st_val + get_mx ( 0 ) + get_mx ( 1 ) ;
    }
    if ( fl == false ) {
        add_up ( x , prv , -1 ) ;
    }
}

int rem[ MAXN ] ;
int same_ans[ MAXN ] , spec[ MAXN ] ;
map < pii , int > present_edges ;

void solve ( ) {
    cin >> n >> m ;
    st.clear ( ) ;
    tp = cnt_comps = 0 ;
    for ( int i = 1 ; i <= n + m ; ++ i ) {
        num[ i ] = 0 ;
        gr[ i ].clear ( ) ;
        v[ i ].clear ( ) ;
        comp[ i ] = 0 ;
        bridge[ i ] = false ;
        seen[ i ] = false ;
        ans[ i ] = 0 ;
        same_ans[ i ] = 0 ;
        spec[ i ] = 0 ;
        cannot[ i ] = false ;
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        cin >> a[ i ] ;
    }
    present_edges.clear ( ) ;
    for ( int i = 1 , x , y ; i <= m ; ++ i ) {
        cin >> x >> y ;
        if ( x == y ) {
            spec[ i ] = 1 ;
            continue ;
        }
        if ( x > y ) { swap ( x , y ) ; }
        if ( present_edges.find ( { x , y } ) != present_edges.end ( ) ) {
            same_ans[ i ] = present_edges[ { x , y } ] ;
            cannot[ i ] = true ;
            cannot[ present_edges[ { x , y } ] ] = true ;
            continue ;
        }
        present_edges[ { x , y } ] = i ;
        gr[ x ].push_back ( { y , i } ) ;
        gr[ y ].push_back ( { x , i } ) ;
    }
    int tot = 0 ;
    for ( int j = 1 ; j <= n ; ++ j ) {
        if ( num[ j ] == 0 ) {
            all_comp.clear ( ) ;
            st.clear ( ) ;
            dfs ( j , -1 ) ;
            for ( auto x : all_comp ) {
                add ( 1 , a[ x ] , 1 ) ;
            }
            st_val = get_mx ( 1 ) ;
            tot += st_val ;
            // printf ( "stval = %d\n" , st_val ) ;
            for ( int i : all_comp ) {
                set < int > foo ;
                foo.clear ( ) ;
                for ( auto [ to , id ] : gr[ i ] ) {
                    if ( seen[ id ] == false ) {
                        ans[ id ] += st_val ;
                        rem[ id ] = st_val ;
                        seen[ id ] = true ;
                    }
                    if ( foo.find ( comp[ id ] ) == foo.end ( ) ) { 
                        // printf ( "edge %d %d\n" , i , n + comp[ id ] ) ;
                        v[ i ].push_back ( n + comp[ id ] ) ;
                        v[ n + comp[ id ] ].push_back ( i ) ;
                        foo.insert ( comp[ id ] ) ;
                    }
                }
            }
            
            init_subtrees ( j , -1 ) ;
            calc ( j , -1 , false ) ;
            for ( auto x : all_comp ) {
                add ( 1 , a[ x ] , -1 ) ;
            }
        }
    }
    // printf ( "hahah --- %d %d\n" , get_mx ( 0 ) , get_mx ( 1 ) ) ;
    // printf ( "here\n" ) ;
    for ( int i = 1 ; i <= m ; ++ i ) {
        if ( spec[ i ] == 1 ) { ans[ i ] = tot ; }
        else if ( same_ans[ i ] == 0 ) { ans[ i ] = ans[ i ] + tot - rem[ i ] ; }
        else { ans[ i ] = ans[ same_ans[ i ] ] ; }
        cout << ans[ i ] << " " ;
    }
    cout << "\n" ;
}

int main ( ) {
    ios_base :: sync_with_stdio ( false ) ;
    cin.tie ( NULL ) ;
    int t = 1 ; cin >> t ; 
    while ( t -- ) { solve ( ) ; }
    return 0 ;
}

详细

Test #1:

score: 0
Wrong Answer
time: 3ms
memory: 17592kb

input:

3
7 5
1 2 1 2 1 2 1
1 2
1 3
2 4
5 6
5 7
3 3
1 2 3
1 2
1 3
2 3
2 3
12345 54321
1 2
1 2
1 1

output:

6 5 5 5 4 
1 1 1 
1 1 1 

result:

wrong answer 1st lines differ - expected: '6 5 5 5 4', found: '6 5 5 5 4 '