【题解】畜栏预定

【题解】畜栏预定

嘿嘿又是普及题

至少要把线段分成多少个集合使得所有相交的线段不在一个集合输出方案。

显然我们让没一个线段覆盖的所有下标加上1,最后查询全局最大值就是答案,这样太显然了。直接树状数组\(O(n \log n)\),或许有\(O(n)\)算法,有没有人教一下我。

然后得到这个集合数目之后直接模拟一下,输出方案即可。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>

using namespace std;  typedef long long ll;
inline int qr(){
      register int ret=0,f=0;
      register char c=getchar();
      while(c<48||c>57)f|=c==45,c=getchar();
      while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
      return f?-ret:ret;
}
const int maxn=50005;
const int maxm=1e6+1;
int seg[maxm];
int Lb;
#define lowbit(x) ((x)&(-x))
int n,m;


inline void add(const int&pos,const int&tag){
      for(register int t=pos;t<=Lb;t+=lowbit(t)) seg[t]+=tag;
}

inline int q(const int&pos){
      register int ret=0;
      for(register int t=pos;t;t-=lowbit(t)) ret+=seg[t];
      return ret;
}

vector < int > ve[maxm];
queue  < int > Q;
int arc[maxn];
int sav[maxn];
int cnt,len;


int main(){
      n=qr();
      for(register int t=1,t1,t2;t<=n;++t){
        t1=qr();t2=qr();
        ve[t1].push_back(t);
        ve[t2+1].push_back(-t);
        Lb=max(Lb,t2+2);
        add(t1,1);add(t2+1,-1);
      }
      
      int ans=0;
      for(register int t=1;t<=Lb;++t)
        ans=max(ans,q(t));
      for(register int t=1;t<=ans;++t) Q.push(t);
      for(register int t=1;t<=Lb;++t) {
        for(register int i=0,ed=ve[t].size();i<ed;++i)
          if(ve[t][i]<0)
            Q.push(arc[-ve[t][i]]);
        for(register int i=0,ed=ve[t].size();i<ed;++i){
          if(ve[t][i]<0)continue;
          arc[ve[t][i]]=Q.front();
          Q.pop();
        }
      }
      arc[0]=ans;
      for(register int t=0;t<=n;++t) printf("%d\n",arc[t]);
      return 0;
}

转载于:https://www.cnblogs.com/winlere/p/11223732.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值