AtCoder Regular Contest 189 (Div. 2)
A
计数
B
折叠差不变
D
观察性质暴力
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define endl '\n'
#define LL long long
const int N = 5e5 + 10;
int n, a[N], l[N], r[N];
LL pre[N], suf[N], b[N];
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = a[i];
l[i] = i - 1; r[i] = i + 1;
pre[i] = pre[i - 1] + a[i];
}
for (int i = n; i >= 1; i--) {
suf[i] = suf[i + 1] + a[i];
}
while (1) {
bool flag = 0;
for (int i = 1; i <= n; i++) {
while (l[i] >= 1 && b[i] > a[l[i]]) {
b[i] += pre[l[i]] - pre[l[l[i]]];
l[i] = l[l[i]];
flag = 1;
}
}
for (int i = n; i >= 1; i--) {
while (r[i] <= n && b[i] > a[r[i]]) {
b[i] += suf[r[i]] - suf[r[r[i]]];
r[i] = r[r[i]];
flag = 1;
}
}
if (!flag) break;
}
for (int i = 1; i <= n; i++) {
cout << b[i] << ' ';
}
}
int main() {
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
// cin >> t;
solve();
return 0;
}
笛卡尔树(特殊)
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define endl '\n'
#define LL long long
const int N = 5e5 + 10;
int n, a[N], ls[N], rs[N], k, stk[N];
LL ans[N], sum[N];
void dfs1(int x) {
sum[x] = a[x];
if (ls[x]) dfs1(ls[x]);
if (rs[x]) dfs1(rs[x]);
if (ls[x]) sum[x] += sum[ls[x]];
if (rs[x]) sum[x] += sum[rs[x]];
}
void dfs(int x, int fa) {
ans[x] = sum[x];
if (fa && ans[x] > a[fa]) ans[x] = ans[fa];
if (ls[x]) dfs(ls[x], x);
if (rs[x]) dfs(rs[x], x);
}
void solve() {
int top = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
while(k > 0 && a[stk[k]] < a[i]) k--;
if (k) rs[stk[k]] = i;
if (k < top) ls[i] = stk[k + 1];
stk[++k] = i;
top = k;
}
dfs1(stk[1]);
dfs(stk[1], 0);
a[0] = a[n + 1] = 1e9 + 7;
for (int i = 1; i <= n; i++) {
if (a[i - 1] < a[i] || a[i] > a[i + 1]) cout << ans[i] << ' ';
else cout << a[i] << ' ';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// cin >> t;
solve();
return 0;
}