1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| const int N = 1e5 + 5,M = 2e5 + 5,Lg = 18; int n,m,K,Q; int A[M],B[M]; int tl[N],tr[N]; vector<int> ScanLine[N]; multiset<int> Scan; int STL[Lg][N],STR[Lg][N]; inline int MinL(int x,int y) { return tl[x] < tl[y] ? x : y;} inline int MaxR(int x,int y) { return tr[x] > tr[y] ? x : y;} int lg[N]; inline int QminL(int l,int r) { int k = lg[r - l + 1]; return MinL(STL[k][l],STL[k][r-(1<<k)+1]); } inline int QmaxR(int l,int r) { int k = lg[r - l + 1]; return MaxR(STR[k][l],STR[k][r-(1<<k)+1]); } inline void init() { read(n);read(K); read(m); for(int i = 1;i <= m;i++) read(A[i]),read(B[i]); for(int i = 1;i <= m;i++) if(A[i] < B[i]) ScanLine[A[i]].push_back(B[i]), ScanLine[min(A[i] + K - 1,B[i] - 1) + 1].push_back(-B[i]); for(int i = 1;i <= n;i++) { for(auto j : ScanLine[i]) if(j > 0) Scan.insert(j); else Scan.erase(Scan.find(-j)); tr[i] = i; if(Scan.size()) tr[i] = max(tr[i],*Scan.rbegin()); ScanLine[i].clear(); } Scan.clear(); for(int i = 1;i <= m;i++) if(A[i] > B[i]) ScanLine[max(A[i] - K + 1,B[i] + 1)].push_back(B[i]), ScanLine[A[i] + 1].push_back(-B[i]); for(int i = 1;i <= n;i++) { for(auto j : ScanLine[i]) if(j > 0) Scan.insert(j); else Scan.erase(Scan.find(-j)); tl[i] = i; if(Scan.size()) tl[i] = min(tl[i],*Scan.begin()); ScanLine[i].clear(); } lg[0] = -1; for(int i = 1;i <= n;i++) STL[0][i] = STR[0][i] = i,lg[i] = lg[i >> 1] + 1; for(int j = 1;j < Lg;j++) for(int i = 1;i + (1 << j) - 1 <= n;i++) STL[j][i] = MinL(STL[j - 1][i],STL[j - 1][i + (1 << j - 1)]), STR[j][i] = MaxR(STR[j - 1][i],STR[j - 1][i + (1 << j - 1)]); } int goL[Lg][N],goR[Lg][N]; inline void initjump() { for(int i = 1;i <= n;i++) goL[0][i] = QminL(tl[i],tr[i]),goR[0][i] = QmaxR(tl[i],tr[i]),assert(tl[i] <= tr[i]); for(int j = 1;j < Lg;j++) for(int i = 1;i <= n;i++) { int l1 = goL[j - 1][i],r1 = goR[j - 1][i]; int l2 = MinL(goL[j - 1][l1],goL[j - 1][r1]); int r2 = MaxR(goR[j - 1][l1],goR[j - 1][r1]); goL[j][i] = l2;goR[j][i] = r2; assert(1 <= l2 && l2 <= n); assert(1 <= r2 && r2 <= n); } } inline int Jump(int S,int T) { int l = S,r = S; int ans = 0; for(int i = Lg - 1;i >= 0;i--) { int i1 = MinL(goL[i][l],goL[i][r]); int i2 = MaxR(goR[i][l],goR[i][r]); if(tl[i1] > T || tr[i2] < T) ans |= (1 << i),l = i1,r = i2; } if(tl[MinL(l,r)] <= T && T <= tr[MaxR(l,r)]) return ans + 1; int i1 = MinL(goL[0][l],goL[0][r]),i2 = MaxR(goR[0][l],goR[0][r]); l = i1;r = i2;++ans;
if(tl[MinL(l,r)] > T || tr[MaxR(l,r)] < T) return -1; return ans + 1; } int main() { init(); initjump(); read(Q); for(int _ = 1;_ <= Q;_++) { int s,t; read(s);read(t); write(Jump(s,t)); } return 0; }
|