成环,把每个区间变成两个然后展开成链
一个人的下一个人肯定是在彼此相交的基础上,右端点越大越好
于是就把它连到相交的、右端点最大的点上,连成一棵树
于是每次只要从某个节点开始,一直在树上跳到覆盖了一个M为止,统计数量
这个可以倍增来做
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=4e5+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 struct Node{ 16 ll l,r;int id; 17 }pos[maxn]; 18 int N,M,ans[maxn]; 19 int fa[maxn][20]; 20 21 inline bool cmp(Node a,Node b){return a.l<b.l;} 22 23 int main(){ 24 //freopen("","r",stdin); 25 int i,j,k; 26 N=rd(),M=rd(); 27 for(i=1;i<=N;i++){ 28 ll a=rd(),b=rd(); 29 if(b<a) b+=M; 30 pos[i].id=i,pos[i+N].id=i+N; 31 pos[i].l=a,pos[i].r=b; 32 pos[i+N].l=a+M,pos[i+N].r=b+M; 33 } 34 sort(pos+1,pos+N*2+1,cmp); 35 for(i=N*2,j=N*2;i;i--){ 36 for(;j>i+1&&pos[j].l>pos[i].r;j--); 37 if(j>i&&pos[j].l<=pos[i].r) 38 fa[i][0]=j; 39 // printf("%d %d ",pos[i].id,pos[fa[i][0]].id); 40 for(k=0;fa[i][k]&&fa[fa[i][k]][k];k++) 41 fa[i][k+1]=fa[fa[i][k]][k]; 42 } 43 for(i=1;i<=N;i++){ 44 int x=i; 45 // printf("%d ",pos[i].id); 46 for(j=18;j>=0;j--){ 47 if(fa[x][j]&&pos[fa[x][j]].r<pos[i].l+M) 48 ans[pos[i].id]+=(1<<j),x=fa[x][j]; 49 }ans[pos[i].id]+=2; 50 } 51 for(i=1;i<=N;i++) 52 printf("%d ",ans[i]); 53 return 0; 54 }