XXI Open Cup, Grand Prix of Belarus 2020-2021 Winter Petrozavodsk Camp, Belarusian SU Contest 题解( 三 )
\([1,2,5,3,2]\),对于这组数来说,最终留下的数一定是5,因为在取出最大值5后,分成了 \([1, 2]\)和$ [3,2]$ 两个区间,但是我们发现两个区间的最大值2和3只能成长到3和4,也就是\([3,5,4]\),所以无法留到最后 。从这里我们可以发现,对于每个分出来的区间,都会有一个区间下限,如果该区间的最大值在成长之后达不到这个下限,那么这个区间就是无法产生“胜者”的 。
【XXI Open Cup, Grand Prix of Belarus 2020-2021 Winter Petrozavodsk Camp, Belarusian SU Contest题解】接下来考虑如何获得每个区间的下限 。我们用三元组\({L, R, V}\)来表示\([L, R]\)这段区间的下限值为\(V\),假设该区间最大值的下标为\(M\),那对于左区间的下限\(V_1\)来说,不仅要“打败"\(a_M\), 还要在删完右区间后达到\(V\), 只有这样才能继续往大的区间吃 。即\(V_1 = Max(a_M,V+M-R-1)\) 。
int n, a[maxn], maxx[maxn * 4];vector ans;void build(int id, int l, int r) {if (l == r) {maxx[id] = l;} else {build(ls, l, mid);build(rs, mid + 1, r);if (a[maxx[ls]] > a[maxx[rs]])maxx[id] = maxx[ls];elsemaxx[id] = maxx[rs];}}int query(int id, int l, int r, int ql, int qr) {if (ql <= l && qr >= r) return maxx[id];if (qr <= mid)return query(ls, l, mid, ql, qr);else if (ql > mid)return query(rs, mid + 1, r, ql, qr);else {int res1 = query(ls, l, mid, ql, mid);int res2 = query(rs, mid + 1, r, mid + 1, qr);if(a[res1] > a[res2]) return res1;else return res2;}}void solve(int l, int r, int maxx) {int pos = query(1, 1, n, l, r);if(a[pos] + r - l < maxx) return;ans.push_back(pos);if(l <= pos - 1) solve(l, pos - 1, max(a[pos], maxx + pos - 1 - r));if(pos + 1 <= r) solve(pos + 1, r, max(a[pos], maxx + l - pos - 1));}int main() {ios;cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];build(1, 1, n);solve(1, n, 0);cout << ans.size() << endl;sort(ans.begin(), ans.end());for (int i : ans) cout << i << " ";}
经验总结扩展阅读
- [CG从零开始] 4. pyopengl 绘制一个正方形
- 在图片不被裁剪时opencv绕图片中任意点旋转任意角度
- OpenDataV低代码平台增加自定义属性编辑
- 含源码 手把手教你使用LabVIEW OpenCV DNN实现手写数字识别
- opencvcv.line
- OpenglEs之三角形绘制
- 含源码 手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用
- Opengl ES之FBO
- 1cup等于多少克
- CUPRA是什么