要求求固定集合中 以点划分区间的最小点个数
将区间以右端点排序贪心计数
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int t,n;
struct node{
int a,b,m;
}p[N];
pair<int,int> ans[N];
vector<node> v[N];
map<int,int> mp;
bool cmp(node A,node B){
if(A.b==B.b) return A.a<B.a;
return A.b<B.b;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int tot=0;mp.clear();
for(int i=1;i<=n;i++){
int a,b,m;
scanf("%d%d%d",&a,&b,&m);
p[i]={a,b,m};
int l=max(0,a-m),r=a-max(0,m-b);
// cout<<l<<" "<<r<<endl;
if(mp[a+b-m]==0){
v[++tot].push_back({l,r,i});
mp[a+b-m]=tot;
}else{
v[mp[a+b-m]].push_back({l,r,i});
}
}
int count=0;
// cout<<tot<<endl;
for(int i=1;i<=tot;i++) {
sort(v[i].begin(),v[i].end(),cmp);
count++; int now=v[i][0].b,id=v[i][0].m;
int r=p[id].a-max(0,p[id].m-p[id].b),B=p[id].b-(p[id].m-p[id].a+r);
ans[id]={r,B};
// cout<<now<<endl;
for(int j=1;j<v[i].size();j++){
// cout<<now<<endl;
if(v[i][j].a<=now&&v[i][j].b>=now){
id=v[i][j].m;
ans[id]={r,B};
continue;
}else{
count++;
id=v[i][j].m;
r=p[id].a-max(0,p[id].m-p[id].b),B=p[id].b-(p[id].m-p[id].a+r);
ans[id]={r,B};
now=v[i][j].b;
}
}
}
printf("%d\n",count);
for(int i=1;i<=n;i++){
printf("%d %d\n",p[i].a-ans[i].first,p[i].b-ans[i].second);
}
cout<<endl;
for(int i=1;i<=tot;i++) v[i].clear();
}
}