我宣称这份代码可以处理区间有包含的情况,可是寄了,求强神。
#include<bits/stdc++.h>
using namespace std;
typedef long double ll;
void rd(int &p){
int f=1;p=0;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}
while(c>='0'&&c<='9')p=(p<<1)+(p<<3)+c-'0',c=getchar();
p*=f;
}
const int N=4e5+50;
int n,m,st[25][N],e[N],g[25][N],b[N];
struct soldier{
int l,r,id;
bool operator<(const soldier &x)const{
return r<x.r;
}
}a[N];
int ask(int l,int r){
if(l>r)return 0;
int d=e[r-l+1];
if(a[st[d][l]].l<a[st[d][r-(1<<d)+1]].l)return st[d][l];
return st[d][r-(1<<d)+1];
}
int main(){
rd(n);rd(m);
for(int i(1);i<=n;++i){
rd(a[i].l);rd(a[i].r);a[i].id=i;
if(a[i].r<a[i].l)a[i].r+=m;
}sort(a+1,a+n+1);
for(int i(n+1);i<=2*n;++i){
a[i].l=a[i-n].l+m;a[i].r=a[i-n].r+m;a[i].id=a[i-n].id;
}
for(int i(1);i<=2*n;++i)st[0][i]=i;
for(int i(1);i<=20;++i){
for(int j(1);j<=(n*2-(1<<i)+1);++j){
if(a[st[i-1][j]].l<a[st[i-1][j+(1<<i-1)]].l)st[i][j]=st[i-1][j];
else st[i][j]=st[i-1][j+(1<<i-1)];
}
}e[1]=0;
for(int i(2);i<=n*2;++i)e[i]=e[i>>1]+1;
// cout<<endl;for(int i(1);i<=2*n;++i)printf("%d %d\n",a[i].l,a[i].r);
// for(int i(0);i<=3;++i){
// for(int j(1);j<=2*n;++j)printf("%d ",st[i][j]);
// printf("\n");
// }
int l,r,mid;
for(int i(1);i<=2*n;++i){
l=0,r=2*n;
while(l<r){
mid=l+r>>1;
if(a[mid].r>=a[i].l)r=mid;
else l=mid+1;
}
b[i]=l;
}//cout<<ask(1,1)<<endl;
// for(int i(1);i<=2*n;++i)printf("%d ",b[i]);cout<<endl;
for(int i(0);i<=2*n;++i)g[0][i]=ask(b[i],i-1);
for(int i(1);i<=20;++i){
for(int j(0);j<=2*n;++j){
g[i][j]=g[i-1][g[i-1][j]];
}
}
// for(int i(0);i<=3;++i){
// for(int j(1);j<=2*n;++j)printf("%d ",g[i][j]);
// printf("\n");
// }
int an[N];l=1e9;
for(int i(n+1),x,ans;i<=2*n;++i){
ans=2;x=i;
for(int j(20);j>=0;--j){
if(a[g[j][x]].l+m>a[i].r)ans+=(1<<j),x=g[j][x];
}
an[a[i].id]=ans;l=min(l,ans);
}
for(int i(1);i<=n;++i)printf("%d ",an[i]);
return 0;
}