这个题需要维护三个变量, 一个是区间最大连续长度, 一个是最长前缀, 一个是最长后缀。 需要注意的就是查询的时候, 先查左区间是否满足, 然后应该查左区间和右区间交界处是否满足, 这里要看pre_max[rt<<1|1]+suf_max[rt<<1|1]是否大于等于给出的长度, 最后才是右区间。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 50005; int maxx[maxn<<2], pre_max[maxn<<2], suf_max[maxn<<2], cover[maxn<<2]; void pushUp(int rt, int m) { maxx[rt] = max(maxx[rt<<1], maxx[rt<<1|1]); pre_max[rt] = pre_max[rt<<1]; suf_max[rt] = suf_max[rt<<1|1]; if(maxx[rt<<1] == (m-(m>>1))) pre_max[rt] = pre_max[rt<<1] + pre_max[rt<<1|1]; if(maxx[rt<<1|1] == (m>>1)) suf_max[rt] = suf_max[rt<<1|1]+suf_max[rt<<1]; maxx[rt] = max(maxx[rt], suf_max[rt<<1]+pre_max[rt<<1|1]); } void build(int l, int r, int rt) { maxx[rt] = pre_max[rt] = suf_max[rt] = r-l+1; cover[rt] = -1; if(l == r) return ; int m = l+r>>1; build(lson); build(rson); } void pushDown(int rt, int m) { if(~cover[rt]) { cover[rt<<1] = cover[rt<<1|1] = cover[rt]; maxx[rt<<1] = pre_max[rt<<1] = suf_max[rt<<1] = cover[rt]*(m-(m>>1)); pre_max[rt<<1|1] = suf_max[rt<<1|1] = maxx[rt<<1|1] = cover[rt]*(m>>1); cover[rt] = -1; } } void update(int L, int R, int l, int r, int rt, int val) { if(L<=l&&R>=r) { cover[rt] = val; maxx[rt] = suf_max[rt] = pre_max[rt] = val*(r-l+1); return ; } pushDown(rt, r-l+1); int m = l+r>>1; if(L<=m) update(L, R, lson, val); if(R>m) update(L, R, rson, val); pushUp(rt, r-l+1); } int query(int val, int l, int r, int rt) { if(l == r) return l; pushDown(rt, r-l+1); int m = l+r>>1; if(maxx[rt<<1]>=val) return query(val, lson); if(pre_max[rt<<1|1]+suf_max[rt<<1]>=val) return m-suf_max[rt<<1]+1; return query(val, rson); } int main() { int n, m, sign, x, y; while(cin>>n>>m) { build(1, n, 1); while(m--) { scanf("%d", &sign); if(sign == 1) { scanf("%d", &x); if(maxx[1]<x) { cout<<0<<endl; } else { int pos = query(x, 1, n, 1); cout<<pos<<endl; update(pos, pos+x-1, 1, n, 1, 0); } } else { scanf("%d%d", &x, &y); update(x, y+x-1, 1, n, 1, 1); } } } }