AGC029C - Lexicographic constraints 题解
看来细节比较多...
显然需要二分.
考虑用贪心来判断当前的 是否可行, 从 枚举到 :
- 如果 , 那么直接在后面添 即可.
- 如果 , 那么贪心, 在 的基础上找到第一个 且值不为 的位置, 然后将它的值 .
如果某次找不到这样的位置了则说明 不行.
考虑到直接维护是 O(值域) 的, 可能接受不了, 但每次修改都是连续的一段.
所以这个东西可以用栈来维护, 那么复杂度就正确了.
贴上代码:
#include <bits/stdc++.h>
#define N 200200
#define fi first
#define se second
#define pii pair<int, int>
using namespace std;
int n, a[N], top;
pii stk[N];
inline bool check(int mid) {
stk[0] = make_pair(0, 0);
stk[top = 1] = make_pair(1, a[1]);
for (int i = 2; i <= n; ++i) {
if (a[i] > a[i - 1]) {
while (top && stk[top].fi == 1)
--top;
stk[++top] = make_pair(1, a[i]);
} else {
int now = 0;
while (top && stk[top].se >= a[i])
now = stk[top--].fi;
if (now < mid) {
if (stk[top].se != a[i] - 1)
stk[++top] = make_pair(now, a[i] - 1);
else while (top && stk[top].fi == now + 1) --top;
stk[++top] = make_pair(now + 1, a[i]);
} else {
if (!top) return false;
now = stk[top].fi;
int pos = stk[top].se;
if (stk[top - 1].se == pos - 1) {
if (top) for (--top; top && stk[top].fi == now + 1; --top);
stk[++top] = make_pair(now + 1, pos);
} else stk[top].se--, stk[++top] = make_pair(now + 1, pos);
stk[++top] = make_pair(1, a[i]);
}
}
}
return true;
}
int main() {
cin >> n;
bool chk = 1;
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
if (a[i] <= a[i - 1]) chk = false;
}
if (chk) return puts("1"), 0;
int l = 2, r = n - 1, res = n;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) r = (res = mid) - 1;
else l = mid + 1;
}
cout << res << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)