P4331 [BalticOI 2004] Sequence 数字序列
[BalticOI 2004] Sequence 数字序列
题目描述
给定一个整数序列
【数据范围】
的数据 ; 的数据 ; 的数据 ;
Solution
Slope trick 入门题。
先将所有
直接做是
将
设计一种方式来表示分段函数。使用分段函数的第一段和一个可重集来表示分段函数,其中可重集中的元素
那么本题中的转移可以看作是加上了
使用优先队列维护这个下凸壳的所有拐点,因为转移是取
对于方案的输出,可以在转移的时候记录决策点,然后倒推出方案。
时间复杂度
Code
// Cirno is not baka!
#include <bits/stdc++.h>
using namespace std;
#ifdef CIRNO
#include <debug.hpp>
#else
#define Debug(...)
#endif
#define For(i, a, b) for (int i = (a); i <= (int)(b); ++i)
#define Rof(i, a, b) for (int i = (a); i >= (int)(b); --i)
#define All(x) x.begin(), x.end()
#define pii pair<int, int>
#define fi first
#define se second
#define i64 long long
#define mkp make_pair
#define int long long
#define epb emplace_back
const int _N = 1e6 + 5, mod = 1e9 + 7, inf = 1e9;
template<typename T> void Max(T &x, T y) {x = max(x, y);}
template<typename T> void Min(T &x, T y) {x = min(x, y);}
namespace BakaCirno {
int N, A[_N], pos[_N];
priority_queue<int> q;
void _() {
cin >> N;
For(i, 1, N) cin >> A[i], A[i] -= i;
int K = 0;
For(i, 1, N) {
K += -1;
q.emplace(A[i]), q.emplace(A[i]);
while (K + q.size() != 0) q.pop();
pos[i] = q.top();
}
Rof(i, N - 1, 1) Min(pos[i], pos[i + 1]);
int ans = 0;
For(i, 1, N) ans += abs(A[i] - pos[i]);
cout << ans << '\n';
For(i, 1, N) cout << pos[i] + i << ' ';
cout << '\n';
}
}
void File(const string file) {
freopen((file + ".in").c_str(), "r", stdin);
freopen((file + ".out").c_str(), "w", stdout);
}
signed main() {
// File("");
cin.tie(0)->sync_with_stdio(0); int T = 1;
// cin >> T;
while (T--) BakaCirno::_();
}
分类:
标签:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步