QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#105357 | #6127. Kawa Exam | Sorting# | WA | 3ms | 17592kb | C++20 | 6.8kb | 2023-05-13 23:03:46 | 2023-05-13 23:03:50 |
Judging History
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 '