The Union of k-Segments
题意
略
解决
- 对点分类,分为左端点和右端点
- 所有点丢到一个vector里按照x坐标升序排序,坐标相同时优先考虑左端点
- 按照区间计数原理,从前往后扫描所有点,扫描到左端点计数器+1,右端点计数器-1,那么计数器>=k的区间都是合法区间
- 通过标记去维护合法区间的起始位置和结束位置,维护答案即可
int ans1[maxn] , ans2[maxn];
struct node
{
int x;
int flag; //左端点为1 右端点-1
node(){}
node(int xx,int ff){
x = xx;
flag = ff;
}
bool operator<(node n2)const{ //坐标相同时左端点在前面
if(x==n2.x) return flag>n2.flag;
return x<n2.x;
}
};
vector<node> vec;
int main()
{
int ll,rr;
int n,k;
scanf("%d%d",&n,&k);
rep(i,1,n+1){
scanf("%d%d",&ll,&rr);
vec.pb(node(ll,1));
vec.pb(node(rr,-1));
}
sort(vec.begin() , vec.end());
//rep(i,0,vec.size()) printf("%d%c",vec[i].x,i+1==vec.size()?'\n':' ');
//rep(i,0,vec.size()) printf("%d%c",vec[i].flag,i+1==vec.size()?'\n':' ');
int tmp = 0;
int flag = 0; //flag=0表示区间开始,为1表示区间结束
int cnt = 0;
rep(i,0,vec.size()){
int xx = vec[i].x;
int ff = vec[i].flag;
tmp += ff;
rr = xx;
if(tmp>=k&&!flag){
flag = 1;
ll = xx;
continue;
}
if(flag && tmp<k){
flag = 0;
ans1[++cnt] = ll;
ans2[cnt] = rr;
}
}
printf("%d\n",cnt);
rep(i,1,cnt+1) printf("%d %d\n",ans1[i],ans2[i]);
}