题目大意:
约翰的N(l
解题思路
差分 贪心 线段树 前缀和
我用的差分
对于一段时间的维护,原本需要将这一段时间都标记上这头牛,但经过差分后就只用标记两个端点,这样时间复杂度就降下来了。然后输出就直接暴力枚举。
Accepted code:
#include<bits/stdc++.h>
#define LL long long
#define res register int
#define inf 0x7ffffff
using namespace std;
const int N=1e5+10,M=1e6+10;
int pos[M],n,maxx,ans,tim[N],pen[N];
struct node{
int l,r,id;
}seg[N];
inline int read(){
int f=0,ag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') ag=-1; c=getchar();}
while(isdigit(c)){f=(f<<3)+(f<<1)+c-48;c=getchar();}
return f*ag;
}
inline bool cmp(node a,node b){
return a.l<b.l;
}
int main(){
n=read();
for(res i=1;i<=n;i++){
int x=read(),y=read();
seg[i]=(node){x,y,i};
pos[x]++,pos[y+1]--;
maxx=max(maxx,y);
}
int a=0;
for(res i=1;i<=maxx;i++){
a+=pos[i];
ans=max(ans,a);
}
printf("%d\n",ans);
sort(seg+1,seg+1+n,cmp);
for(res i=1;i<=n;i++)
for(res k=1;k<=ans;k++)
if(pen[k]<seg[i].l){
pen[k]=seg[i].r,tim[seg[i].id]=k;break;
}
for(res i=1;i<=n;i++)
printf("%d\n",tim[i]);
return 0;
}