1490E - Accidental Victory
// 思路
毫无疑问如果数字为x能赢,那么>=x的都能取胜,反之如果x不能赢,小于x的都不能取胜。
典型的二分
只需找到这个临界的x就行。
那么让x能赢最优操作无疑是先让x和比他小的比,吃小的分,在和后面比。
以此设计check()函数即可
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 200010 ;
pair< int , int > a[ N] ;
int b[ N] ;
ll sum[ N] ;
int n;
bool check ( int mid)
{
int t = mid + 1 ;
while ( t <= n && sum[ mid] >= a[ t] . first)
{
if ( t == n) return true;
mid = t;
t ++ ;
}
return false;
}
int main ( )
{
ios: : sync_with_stdio ( false) ;
cin. tie ( 0 ) ;
cout. tie ( 0 ) ;
int t;
cin >> t;
while ( t -- )
{
cin >> n;
sum[ 0 ] = 0 ;
for ( int i = 1 ; i <= n; i ++ )
{
int x;
cin >> x;
a[ i] = { x, i} ;
}
sort ( a + 1 , a + 1 + n) ;
for ( int i = 1 ; i <= n; i ++ ) sum[ i] = sum[ i - 1 ] + a[ i] . first;
int l = 1 , r = n;
while ( l < r)
{
int mid = l + r >> 1 ;
if ( check ( mid) ) r = mid;
else l = mid + 1 ;
}
int t = 0 ;
for ( int i = l; i <= n; i ++ )
{
b[ ++ t] = a[ i] . second;
}
sort ( b + 1 , b + 1 + t) ;
cout << t << endl;
for ( int i = 1 ; i <= t; i ++ ) cout << b[ i] << ' ' ;
cout << endl;
}
}