思路:
从左边往右边考虑,F[x]为区间[0,x]的解。因此所求为F[L]。
首先可以推断出,以下几点

  1. x 为偶数,因为洒水是以原点为中心画圆,所有直径不可能为奇数。

  2. F[x] = F[y]min + 1, y = [x-2B, x-2A]。 因为半径为A——B,所有只有x-2B 到 x-2A 之间才能通过再加一个点达到x。
    那么如何快速求得[x-2B, x-2A]中的y,使得F[y]最小?需要使用优先队列,在每次完成一个点的计算之后,增加计算下一个点所需的信息到优先队列中。

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <limits.h>
    #include <iomanip>
    #include <queue>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    typedef vector<int> vec;
    //#pragma GCC optimize(2)
    const static int INFINITE = 1<<30;
    static int N, L, A, B;
    static vector<int> Is(1000010);
    static vector<int> F(1000010);
    struct node{
     node(int _x, int _fx): x(_x), fx(_fx) {}
     int x;
     int fx;
    
     bool operator<(const node& a) const{
         return fx > a.fx;
     }
    };
    static priority_queue<node> q;
    int main()
    {
    
     freopen("E:\\Desktop\\data.txt", "r", stdin);
     //ios::sync_with_stdio(false);
    
     cin >> N >> L >> A >> B;
     A <<= 1;
     B <<= 1;
    
     for (int i = 0; i < N; i++) {  //使用查分,快速求得那些点有奶牛
         int s, t;
         cin >> s >> t;
         Is[s+1]++;
         Is[t]--;
     }
    
     int cc = 0;
     for (int i = 0; i <= L; i++) {
         F[i] = INFINITE;
         cc += Is[i];
         Is[i] = cc > 0;
     }
    
     for (int i = A; i <= B; i+=2) {  //初始化优先队列
         if(! Is[i]){
             F[i] = 1;
             if(i <= B+2-A)
                 q.push(node(i, 1));
         }
     }
    
     for (int i = B+2; i <= L; i+=2) {
    
         if(! Is[i]){       //使用优选队列,根据F[x] = F[y]min + 1 求F[x]
             node cc(0, 0);
             while (! q.empty()) {
                 cc = q.top();
                 if(cc.x < i - B)
                     q.pop();
                 else
                     break;
             }
    
             if(! q.empty())
                 F[i] = cc.fx + 1;
         }
    
         if(F[i+2-A] != INFINITE)  // 为求F[x+1]做准备
             q.push(node(i+2-A, F[i+2-A]));
     }
    
     if(F[L] == INFINITE)
         cout << -1 << endl;
     else {
         cout << F[L] << endl;
     }
     return 0;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

```