1. 题意梗概
袋子里有 N 个球,有 Q 次询问,每次询问临时拿出 K 个指定的球,求袋子里剩下的球中数字的最小值。询问结束后把球放回。
N≤3×105;Q≤2×105;K≤5
2. 逻辑推导
1. 切入点
这题的突破点在于 k≤5 哈。最小值的可能性是固定的。
2. 思路分析
注意到 k≤5,意味着每次查询的答案数据规模是固定的,最坏的情况是拿出了五个最小的球,答案就是第六小的球,由此发现虽然 N≤3e5 但实际能用的数据只有前 6 个最小的。
那么提前把这 6 个提取出来,然后每次用取出的球 和 前六小的球 进行匹配,这样就解决了这个查询问题。
3. 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| struct Ball { int val, id; } a[maxn]; int n, q, k; int b[10];
bool cmp( Ball a, Ball b ) { if( a.val != b.val ) return a.val < b.val; return a.id < b.id; }
void solve( ) { cin >> n >> q; for( int i = 1; i <= n; ++ i ) { cin >> a[i].val; a[i].id = i; }
sort( a + 1, a + n + 1, cmp );
vector< Ball > tmp; int cnt = min( 6, n ); for( int i = 1; i <= cnt; ++ i ) tmp.push_back( a[i] );
while( q -- ) { cin >> k; for( int i = 1; i <= k; ++ i ) cin >> b[i];
for( const auto &ball : tmp ) { bool rmv = 0; for( int i = 1; i <= k; ++ i ) { if( ball.id == b[i] ) { rmv = 1; break; } } if( rmv == 0 ) { cout << ball.val << '\n'; break; } } } }
|