线段树优化 dp
无解的情况判成有解,不知道为啥
#include <bits/stdc++.h>
using namespace std;
constexpr int L = 1e6+5, LS = 4e6+5, INF = 1e8;
//#define int long long
int symb[L], vs[L], vn = 0, n, l, ra, rb;
int lrange[LS], rrange[LS], val[LS];
inline int maxi(int a, int b) {
return a > b ? a : b;
}
inline int mini(int a, int b) {
return a < b ? a : b;
}
#define lch (root<<1)
#define rch ((root<<1)|1)
#define mids() int mid = (lrange[root] + rrange[root]) >> 1
#define lcall lch, maxi(lrange[root], l), mini(mid, rrange[root])
#define rcall rch, maxi(mid+1, l), mini(rrange[root], r)
void build(int root, int l, int r) {
if (l > r) return;
lrange[root] = l; rrange[root] = r;
val[root] = INF; // i.e., not available...
if (l == r) return;
mids();
build(lch, l, mid);
build(rch, mid+1, r);
}
int query(int root, int l, int r) {
if (l > r) return INF;
if (lrange[root] >= l && rrange[root] <= r) return val[root];
mids();
return mini(query(lcall), query(rcall));
}
// Single point update only
void update(int root, int pos, int value) {
if (lrange[root] == pos && rrange[root] == pos) {
val[root] = value;
return;
}
mids();
if (pos <= mid) {
update(lch, pos, value);
} else {
update(rch, pos, value);
}
// Necessary to pushup
val[root] = mini(val[lch], val[rch]);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>l>>ra>>rb;
for (int i = 1; i <= n; i++) {
int s,e;
cin>>s>>e;
symb[s+1]++;
symb[e]--; // Allowed directly there
}
ra<<=1; rb<<=1;
vs[++vn] = 0;
for (int i = 1; i <= l; i++) { // Consider that the latter point manages sequence
if (i > 0) symb[i] += symb[i-1]; // i.e. point i --> (i-1, i] sequence
if ((i % 2 == 0) && symb[i] == 0) vs[++vn] = i;
}
// cerr << "valid positions are:\n";
// for (int i = 1; i <= vn; i++) cerr<<vs[i]<<' ';
// cerr<<endl;
// assert(vs[vn] == l);
build(1, 1, vn);
update(1, 1, 0);
// cerr << "end of build\n";
for (int i = 2; i <= vn; i++) {
if (vs[i]-ra < 0) continue;
int leftmost = lower_bound(vs+1,vs+vn+1,maxi(0, vs[i]-rb))-vs;
int rightmost = upper_bound(vs+1,vs+vn+1,vs[i]-ra)-vs-1;
int cans = query(1, leftmost, rightmost);
// cerr << vs[i] << "@" << i << " confirmed [" << leftmost << "," << rightmost << "] = " << cans << "\n";
update(1, i, cans + 1);
}
int res = query(1, vn, vn);
if (res >= INF) cout<<"-1"<<endl;
else cout<<res<<endl;
return 0;
}