当前位置: 首页 > news >正文

题解:AT_agc028_e [AGC028E] High Elements

题意:给出一个序列,要求把这个序列分成两个序列,要求这两个序列的前缀极大值的个数相同,给出字典序最小的构造。

做法:

首先肯定是逐位确定,那么假设第一个序列目前有 \(a\) 个最大值,第二个序列有 \(b\)。注意到原序列的前缀极大值分到两个序列中肯定还是前缀极大值,我们研究这个前缀极大值的一些性质。

经过一些手玩可以发现,对于这两个序列剩余的部分中,一定存在一个解满足其中一个序列中的极大值完全由原序列的极大值构成。

考虑如何证明,如果两个序列中都存在不在原序列中的极大值,那么我们令他们交换,在第一个序列中的改成在第二序列中,第二序列中的改在第一序列中,发现他们会同时被消掉,所以可以满足。

那么我们不妨假设第一个序列极大值完全由原序列组成,我们发现,如果我们确定了第二个序列中哪些数由极大值构成,那么我们就直接确定了第一个序列,同时也需要满足我下一个数要比目前第二个序列的极大值要大。

假设我剩下 \(k\) 个极大值,\(t\) 个被第二个序列用掉,第二个序列剩下包括原序列极大值的极大值个数为 \(l\),那么要求 \(a+k-t=l+b,a+k-b=t+l = 2t+(l-t)\)。考虑右侧的意义,我们令原序列中极大值权为 \(2\),剩余的为 \(1\),那么我们就等于能找到一个上升子序列的权等于 \(a+k-b\)

判定很难做,但是我们注意到我们可以无代价地将一个原序列极大值塞进第一个序列,塞完之后也可以塞剩余的 \(l-t\),所以发现我们其实只需要对于 \(l-t \bmod 2=1\)\(l-t \bmod 2=0\) 两种情况分别统计最大值即可,直接用线段树维护带权 lis 最大值即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5 + 5, inf = 2e9;
struct node {int v[2];friend node operator+(node x, node y) {return node{max(x.v[0], y.v[0]), max(x.v[1], y.v[1])};}node() {v[0] = v[1] = -inf;}node(int V0, int V1) {v[0] = V0, v[1] = V1;}
} ;
struct Segtree {node tr[maxn << 2];void pushup(int t) {tr[t] = tr[t << 1] + tr[t << 1 | 1];}void modify(int l, int r, int pos, int t, node val) {if(l == r) {tr[t] = val;return ;}int mid = l + r >> 1;if(pos <= mid)modify(l, mid, pos, t << 1, val);elsemodify(mid + 1, r, pos, t << 1 | 1, val);pushup(t);}node query(int l, int r, int x, int y, int t) {if(x > y)return node();if(x <= l && r <= y)return tr[t];int mid = l + r >> 1;if(y <= mid)return query(l, mid, x, y, t << 1);if(mid < x)return query(mid + 1, r, x, y, t << 1 | 1);return query(l, mid, x, y, t << 1) + query(mid + 1, r, x, y, t << 1 | 1);}
} tree;
node res[maxn];
int n, p[maxn], use[maxn], mx, r;
string s;
bool chk(int v, int x) {if(x < 0)return 0;node t = tree.query(1, n + 1, v + 1, n + 1, 1);
//	cout << x << " " << v << "Adsfdsaf" << " " << t.v[x % 2] << endl;return t.v[x % 2] >= x;
}
signed main() {cin >> n;for (int i = 1; i <= n; i++) {cin >> p[i];if(p[i] > mx) {mx = p[i];use[i] = 1;r++;}}tree.modify(1, n + 1, n + 1, 1, node(0, -inf - 1));for (int i = n; i >= 1; i--) {node t = tree.query(1, n + 1, p[i] + 1, n + 1, 1);res[i].v[0] = t.v[1 ^ use[i]] + use[i] + 1,res[i].v[1] = t.v[0 ^ use[i]] + use[i] + 1;tree.modify(1, n + 1, p[i], 1, res[i]);//	cout << res[i].v[0] << " " << res[i].v[1] << endl;}int nwx = 0, nwy = 0, edx = 0, edy = 0;for (int i = 1; i <= n; i++) {r -= use[i];tree.modify(1, n + 1, p[i], 1, node());int tox = nwx + (p[i] > edx);//	cout << edx << "asdf " << nwy - tox + r << endl;if(chk(edy, tox - nwy + r) || chk(edx, nwy - tox + r)) {s += '0';nwx = tox;edx = max(edx, p[i]);}else {s += '1';nwy += (p[i] > edy);edy = max(edy, p[i]);}//	cout << nwx << " " << nwy << endl;}if(nwx != nwy)cout << -1 << endl;elsecout << s << endl;return 0;
}
http://www.zskr.cn/news/56730.html

相关文章:

  • CSP-J2025总结
  • MineContext:我第一次感觉 AI 真正在“主动帮我管理生活”
  • NCHU OOP-BLOG1-电梯调度-23207329-姚子康 - 翊尘
  • 操作系统的基本概念
  • 开发智联笔记项目时所遇问题(8)
  • NCHU-23207335-面向对象程序设计-BLOG-1
  • 卡码网94: bellman_ford算法
  • 题解:AT_agc067_d [AGC067D] Unique Matching
  • 计算机视觉——从环境配置到跨线计数的完整实现基于 YOLOv12 与质心追踪器的实时人员监控优秀的系统
  • CTF reverse入门记录
  • 上海金蝶代理商推荐——上海宝蝶信息技术有限公司
  • 11.21模拟赛
  • HTML---------------图片转换(草稿)
  • 爱与时间反应鲜红色慢慢退却 一次次重复直到忘记了誓言
  • Agent skills 实战
  • Vue 路由的学习
  • P8809 [蓝桥杯 2022 国 C] 近似 GCD 题解
  • 估值 7 亿美元,Wispr 要做语音操作系统,还要自研 ASR;马斯克:实时视频理解和生成是未来丨日报
  • day27-MCP进阶
  • Day42:2025年11月1日,星期六,值班,诸事皆顺。
  • Day38:2025年10月28日,星期二,值班,诸事皆顺。
  • Day32-35:2025年10月22日-25日,湖北襄阳、恩施州等地出差。
  • 用java写个小游戏
  • NCHU-温馨-BLOG1-单步电梯调度程序 - NCHU
  • 2025年评价高的四川泡椒竹笋加工厂TOP3排行榜
  • Windows打印后台处理程序严重漏洞分析与修复方案
  • 从MongoDB到国产数据库:一场2TB电子证照体系的“平滑着陆”实践
  • 预学习
  • 2025 年知名的成都二手集装箱公司最新 TOP 排行榜
  • 2025-11-20