CodeForces 612D The Union of k-Segments(排序+区间计数、扫描线)

博客探讨了CodeForces 612D问题,即找到k个区间的并集。通过点的分类(左端点和右端点),将它们按坐标排序,并应用区间计数和扫描线算法来确定合法区间,从而解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The Union of k-Segments

题意

解决

  1. 对点分类,分为左端点和右端点
  2. 所有点丢到一个vector里按照x坐标升序排序,坐标相同时优先考虑左端点
  3. 按照区间计数原理,从前往后扫描所有点,扫描到左端点计数器+1,右端点计数器-1,那么计数器>=k的区间都是合法区间
  4. 通过标记去维护合法区间的起始位置和结束位置,维护答案即可
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]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值