当前位置: 首页 > 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.jsqmd.com/news/47029/

相关文章:

  • 基于单片机的篮球比赛计时与比分控制系统设计 - 详解
  • CSP-J2025总结
  • nju实验二 译码器和编码器
  • 如何最低成本注册一个域名?
  • 第四十六篇
  • 2025年送礼水果排行榜权威推荐,拉吾尤摩赣南脐橙荣登榜首
  • AI救星!8个写毕业论文的实用AI工具大揭秘
  • 数据血缘图在数据错误追溯中的应用指南
  • Luogu P10778 BZOJ3569 DZY Loves Chinese II 题解 [ 紫 ] [ Xor Hashing ] [ 线性基 ] [ DFS 树 ]
  • CSS基础语法 - 指南
  • MineContext:我第一次感觉 AI 真正在“主动帮我管理生活”
  • NCHU OOP-BLOG1-电梯调度-23207329-姚子康 - 翊尘
  • 操作系统的基本概念
  • 「Temp」目录
  • Linksys HTTPd缓冲区溢出远程代码执行漏洞深度解析
  • .NET+AI | MEAI | Function Calling 基础(3)
  • 开发智联笔记项目时所遇问题(8)
  • 高中学习机五大品牌终极横评:优缺点一览,找到最适合你的那一款!
  • NCHU-23207335-面向对象程序设计-BLOG-1
  • 开发智联笔记项目时所遇问题(4)
  • 开发智联笔记项目时所遇问题(3)
  • 20251121周五日记
  • 卡码网94: bellman_ford算法
  • CrewAI 上手攻略:多 Agent 自动化处理复杂任务,让 AI 像员工一样分工协作
  • 题解:AT_agc067_d [AGC067D] Unique Matching
  • 开发智联笔记项目所遇问题
  • 计算机视觉——从环境配置到跨线计数的完整实现基于 YOLOv12 与质心追踪器的实时人员监控优秀的系统
  • 搜维尔科技:利用MANUS数据手套实现灵巧远程操作:对20自由度灵巧手进行控制
  • 2025-11-21 早报新闻
  • CTF reverse入门记录