This was the second problem I attempted, I expected to solve it in 15 mins and I made the first submission at 12minuts but wrong answer, it took me another 10 mins to debug.
It looks a lot like a DP, but $p$ is too large, since “simple problems” contribute $0$ to the answer, a greedy idea is that none of the solutions should contain any “simple problem”.
Obviously, the function of solving time and the number of problems solved is monotonic. Use binary search to find the number of problems solved. $O(n\log^2)$
There’s a more elegant global greedy approach. First sort all problems with the first key as difficulty in descending order, and the second key as score in ascending order. Maintain a priority queue and the current minimum difficulty of all problems. Each time pop the problem with the longest time from the queue, then insert other problems into the queue. The condition is that the difficulty of the problem must be $\geq$ the minimum difficulty in the priority queue. $O(n\log)$
Previously I used to write a separate function for verifying the answer in binary search. This time, in a rush, I wrote it together with the main function, leanding to a typo while updating the answer. It took me 10mins to find the issue:(
// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x),__VA_ARGS__})
#define cmax(x,...) x=max({(x),__VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define uint unsigned long long
#define MAXN 200010
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, m; cin >> n >> m;
vector<pair<int, int>> a(n);
vector<int> f;
rep(i, 0, n) cin >> a[i].first >> a[i].second;
int L = 0, R = n;
int ans = 0;
while (L <= R) {
int mid = (L + R) >> 1;
vector<pair<int, int>> v;
rep(i, 0, n) if (a[i].first >= mid) v.push_back({a[i].second, i});
bool valid = 0;
vector<int> tmp;
if (sz(v) >= mid) {
sort(v.begin(), v.end());
int t = 0;
rep(i, 0, mid) {
t += v[i].first;
tmp.push_back(v[i].second);
}
valid = t <= m;
}
if (valid) {
ans = mid;
f = tmp;
L = mid + 1;
}
else R = mid - 1;
}
cout << ans << endl << ans << endl;
rep(i, 0, sz(f)) cout << f[i]+1 << " \n"[i==sz(f)-1];
return 0;
}