线段树+二分的做法,思路是维护可用时间的最小值,80pts,看了一圈没有这个分数的,求调 /bx
#include <bits/stdc++.h>
#define F(i, a, b) for(int (i)=(a); (i)<=(b); ++(i))
#define int long long
using namespace std;
const int N = 2e5 + 5;
void read(int &x) {
x = 0; char ch = getchar(); bool f = 0;
while(!isdigit(ch)) f|=(ch=='-'), ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0', ch=getchar();
x=f?-x:x;
}
struct node {
int id, st, t;
bool operator< (const node rhs) const{
return st < rhs.st;
}
}e[N];
int n, m;
struct segmentTree{
int l, r;
int Min;
}tree[N << 2];
void pushup(int p) {
tree[p].Min = min(tree[p << 1].Min, tree[p << 1 | 1].Min);
}
void build(int p, int l, int r) {
tree[p].l = l; tree[p].r = r;
if(l == r) return;
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
}
void update(int p, int x, int delta) {
if(tree[p].l > x || tree[p].r < x) return;
if(x == tree[p].l && tree[p].r == x) {
tree[p].Min = delta;
return;
}
int mid = (tree[p].l + tree[p].r) >> 1;
update(p << 1, x, delta);
update(p << 1 | 1, x, delta);
pushup(p);
}
int query(int p, int L, int R) {
if(L > tree[p].r || R < tree[p].l) {
return 0;
}
if(L <= tree[p].l && tree[p].r <= R) {
return tree[p].Min;
}
int ans = 2147483647;
int mid = (tree[p].l + tree[p].r) >> 1;
if(L <= mid) ans = min(ans, query(p << 1, L, R));
if(R > mid) ans = min(ans, query(p << 1 | 1, L, R));
pushup(p);
return ans;
}
vector<int> v[N];
signed main() {
// freopen("print.in", "r", stdin);
// freopen("print.out", "w", stdout);
read(n); read(m);
F(i, 1, n) {
int st, t;
read(t); read(st);
e[i] = {i, st, t};
}
sort(e + 1, e + n + 1);
build(1, 1, m);
F(i, 1, n) {
int l = 1, r = m;
bool f = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(query(1, 1, mid) <= e[i].st) {
r = mid - 1; f = 1;
}
else l = mid + 1;
}
if(f == 0) { // 无可用的,找可用时间的最小值
int Max = query(1, 1, m);
int l = 1, r = m, ans = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(query(1, 1, mid) > Max) {
l = mid + 1;
}
else r = mid - 1, ans = mid;
}
update(1, ans, Max + e[i].t);
v[ans].push_back(e[i].id);
}
else { // 有可用的
update(1, l, e[i].st + e[i].t);
v[l].push_back(e[i].id);
}
}
F(i, 1, m) {
cout << v[i].size() << ' ';
sort(v[i].begin(), v[i].end());
for(auto it : v[i]) {
cout << it << ' ';
}
cout << '\n';
}
}