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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include <bits/stdc++.h> using namespace std; using ll = long long;
const int maxn = 1e6 + 50;
ll a[maxn]; int n; ll C;
struct Node { int l, r; ll mx; } tr[ maxn << 2 ];
#define ls ( u << 1 ) #define rs ( u << 1 | 1 )
void push_up( int u ) { tr[u].mx = max( tr[ls].mx, tr[rs].mx ); }
void build( int u, int l, int r ) { tr[u] = { l, r, 0 }; if( l == r ) { tr[u].mx = C; return ; } int mid = ( l + r ) >> 1; build( ls, l, mid ); build( rs, mid + 1, r ); push_up( u ); }
void update( int u, int idx, ll val ) { if( tr[u].l == tr[u].r ) { tr[u].mx = val; return ; } int mid = ( tr[u].l + tr[u].r ) >> 1; if( idx <= mid ) update( ls, idx, val ); else update( rs, idx, val ); push_up( u ); }
int query( int u, ll val ) { if( tr[u].l == tr[u].r ) return tr[u].l; if( tr[ls].mx >= val ) return query( ls, val ); else return query( rs, val ); }
ll remain[maxn];
int solve1( ) { build( 1, 1, n ); for( int i = 1; i <= n; ++ i ) remain[i] = C;
int max_idx = 0; for( int i = 1; i <= n; ++ i ) { int idx = query( 1, a[i] ); max_idx = max( max_idx, idx );
remain[idx] -= a[i]; update( 1, idx, remain[idx] ); } return max_idx; }
int solve2( ) { multiset< ll > s; for( int i = 1; i <= n; ++ i ) { auto it = s.lower_bound( a[i] ); if( it == s.end( ) ) { s.insert( C - a[i] ); } else { ll val = *it - a[i]; s.erase( it ); s.insert( val ); } } return s.size( ); }
void solve( ) { cin >> n >> C; for( int i = 1; i <= n; ++ i ) cin >> a[i];
int first = solve1( ); int best = solve2( ); cout << first << " " << best << '\n'; }
int main( ) { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int _t = 1; cin >> _t; while( _t -- ) { solve( ); } return 0; }
|