#include<bits/stdc++.h> #define endl '\n' usingnamespace std; typedeflonglong ll; typedef pair<int,int> PII; constint N = 2e5 + 10; constint mod = 1e9 + 7; structnode{ int idx; int s,e; }line[2*N]; int n, m, power; vector<vector<int>> st; vector<int> ans; // 将环状展开为线性 intlgp(int n){ int ans = 0; while((1<<ans)<=(n>>1)){ ans++; } return ans; } voidbuild(){ /*如C(6,1),m=8 * 有1 2 3 4 5 6 7 8 9 10 11 ... 1 2 3... 故转化后的C是(6,9) */ for (int i = 1;i<=n;i++){ if (line[i].s>line[i].e){ line[i].e+=m; } } // 按起始点排序 sort(line+1,line+1+n,[&](const node a, const node b){return a.s<b.s;}); // 对点在线性上进行复制即 A B C D A' B' C' D' for(int i =1;i<=n;i++){ line[i+n].idx = line[i].idx; line[i+n].s = line[i].s+m; line[i+n].e = line[i].e+m; } // 新线段数量 int e = n<<1; // 寻找跳一步的最大值, 应满足下一条线段开头<=当前线段结尾 /*如线段开头如下 3 34 56 89 102 到102就超过了结尾,故选择到89 */ for (int i =1, j = 1;i<=e;i++){ while(j+1<=e&&line[j+1].s<=line[i].e){ j++; } st[i][0]=j; } // 倍增 for (int p = 1; p<=power; p++){ for (int i = 1;i<=e;i++){ st[i][p]=st[st[i][p-1]][p-1]; } } } intjump(int i){ // i号线段的目标点是line[i].s+m int tar = line[i].s+m,cur = i, next, ans = 1; for(int p = power; p>=0;p--){ next = st[cur][p]; if (next!=0&&line[next].e<tar){ ans+=1<<p; cur = next; } } return ans+1; // 计算的是小于目标点,+1即为到达
} voidsolve(){ cin >> n >> m; for(int i =1;i<=n;i++){ line[i].idx = i; cin >> line[i].s >> line[i].e; } power = lgp(n); st = vector<vector<int>>(2*n+1, vector<int>(power+1,0)); ans = vector<int>(n+1,0); build(); for (int i = 1;i<=n;i++){ ans[line[i].idx] = jump(i); } for (int i = 1;i<=n;i++) cout << ans[i]<<' ';
} intmain() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int tomorin=1; //cin >> tomorin; while (tomorin--) solve(); return0; }