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

来源:互联网 发布:电影魔方软件 编辑:程序博客网 时间:2024/06/05 04:48

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]);}
阅读全文
0 0