// CTEAM 039 // vdaka ;) #include #include #include #include void solveProblem() { int N; scanf( "%d", &N ); int a[N+1]; int b[N+1]; int frontCount [100000]; int rightCount [100000]; for (int i = 0; i < 100000; i++) { frontCount [i] = 0; rightCount [i] = 0; } int tmp; for( int i = 0; i < N; i++ ) { scanf( "%d", &tmp ); a[i] = tmp; frontCount [tmp-1] ++; } for( int i = 0; i < N; i++ ) { scanf( "%d", &tmp ); b[i] = tmp; rightCount [tmp-1] ++; } int result_min = 0, result_max = 0; for (int i = 0; i < 100000; i++) { if (frontCount [i] > rightCount [i]) result_min += frontCount [i] * (i+1); else if (rightCount [i] > frontCount [i]) result_min += rightCount [i] * (i+1); else if (rightCount [i] > 0) result_min += rightCount [i] * (i+1); } a[N]=b[N] = -1; std::sort( a, a+N, std::greater() ); std::sort( b, b+N, std::greater() ); int ia,ib,ic,id; for( ia = ib = 0; ia < N || ib < N; ) { ic = ia; id = ib; if( a[ia] == b[ib] && ia < N && ib < N ) { do ic++; while( a[ia] == a[ic] ); do id++; while( b[ib] == b[id] ); result_max += a[ia] * ( (ic - ia ) * id + (id-ib)*ia ); // printf( "== %d\n", result_max ); ia = ic; ib = id; } else if( a[ia] > b[ib] && ia < N) { do ic++; while( a[ia] == a[ic] ); result_max += a[ia] * ( (ic - ia ) * ib ); // printf( "== %d\n", result_max ); ia = ic; } else { do id++; while( b[ib] == b[id] ); result_max += b[ib] * ( (id-ib)*ia ); // printf( "== %d\n", result_max ); ib = id; } } printf( "Minimalni budova obsahuje %d kostek, maximalni %d kostek.\n" ,result_min, result_max ); } int main() { int K; scanf( "%d", &K ); while( K-- ) { solveProblem(); } return 0; }