线段树二分板子
//[1,x]内, 找一个最大的位置p, 使得[p,x]的和>=v void find(int o, int l, int r) { if (p!=-1) return; if (r<=x) { if (l==r) { if (s[o]>=v) p = l; else v -= s[o]; return; } pd(o,l,r); if (s[rc]>=v) return find(rs); v -= s[rc]; return find(ls); } pd(o,l,r); if (mid>=x) return find(ls); find(rs),find(ls); } //[x,n]内, 找一个最小的位置p, 使得[x,p]的和>=v void find(int o, int l, int r) { if (p!=-1) return; if (x<=l) { if (l==r) { if (s[o]>=v) p = l; else v -= s[o]; return; } pd(o,l,r); if (s[lc]>=v) return find(ls); v -= s[lc]; return find(rs); } pd(o,l,r); if (mid<x) return find(rs); find(ls),find(rs); } //[1,x]内, 找一个最小的位置p, 使得[p,x]的和<=v void find(int o, int l, int r) { if (x==-1) return; if (r<=x) { if (l==r) { if (s[o]<=v) v -= s[o], p = l; else x = -1; return; } pd(o,l,r); if (s[rc]>=v) return find(rs); //这里不要忘记设置p的值 p = mid+1, v -= s[rc]; return find(ls); } pd(o,l,r); if (mid>=x) return find(ls); find(rs),find(ls); } //[x,n]内, 找一个最大的位置p, 使得[x,p]的和<=v void find(int o, int l, int r) { if (x==-1) return; if (x<=l) { if (l==r) { if (s[o]<=v) v -= s[o], p = l; else x = -1; return; } pd(o,l,r); if (s[lc]>=v) return find(ls); p = mid, v -= s[lc]; return find(rs); } pd(o,l,r); if (mid<x) return find(rs); find(ls),find(rs); } //[1,x]内, 找一个最大的位置p, 使得[p,x]的最小值<=v void find(int o, int l, int r) { if (p!=-1) return; if (r<=x) { if (l==r) { if (mi[o]<=v) p = l; return; } pd(o,l,r); if (mi[rc]<=v) return find(rs); return find(ls); } pd(o,l,r); if (mid>=x) return find(ls); find(rs),find(ls); } //[x,n]内, 找一个最小的位置p, 使得[x,p]的最小值<=v void find(int o, int l, int r) { if (p!=-1) return; if (x<=l) { if (l==r) { if (mi[o]<=v) p = l; return; } pd(o,l,r); if (mi[lc]<=v) return find(ls); return find(rs); } pd(o,l,r); if (mid<x) return find(rs); find(ls),find(rs); } //[1,x]内, 找一个最小的位置p, 使得[p,x]的最小值>=v void find(int o, int l, int r) { if (x==-1) return; if (r<=x) { if (l==r) { if (mi[o]>=v) p = l; else x = -1; return; } pd(o,l,r); if (mi[rc]<v) return find(rs); p = mid+1; return find(ls); } pd(o,l,r); if (mid>=x) return find(ls); find(rs),find(ls); } //[x,n]内, 找一个最大的位置p, 使得[x,p]的最小值>=v void find(int o, int l, int r) { if (x==-1) return; if (x<=l) { if (l==r) { if (mi[o]>=v) p = l; else x = -1; return; } pd(o,l,r); if (mi[lc]<v) return find(ls); p = mid; return find(rs); } pd(o,l,r); if (mid<x) return find(rs); find(ls),find(rs); }