I Hate ARC
arc 太难了。abc 真简单。
从左往右扫描线,用一棵权值线段树维护每种数最后出现的位置。
考虑扫到点
我们设线段树维护的每个数
考虑到需要维护的东西是单调递减序列。于是直接楼房重建即可。
时间复杂度两只老哥。
::::success[Code]
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using uint = unsigned int;
using i128 = __int128;
using PII = pair<int, int>;
using PLL = pair<ll, ll>;
#define fi first
#define se second
#define rep(i, j, k) for (int i = (j); i < (k); i++)
#define rrep(i, j, k) for (int i = (j); i > (k); i--)
#define _rep(i, j, k, l) for (int i = (j); i < k; i += l)
#define _rrep(i, j, k, l) for (int i = (j); i > k; i -= l)
#define __rep(i, j, k) for (int i = (j); i <= (k); i++)
#define __rrep(i, j, k) for (int i = (j); i >= (k); i--)
#define ___rep(i, j, k, l) for (int i = (j); i <= k; i += l)
#define ___rrep(i, j, k, l) for (int i = (j); i >= k; i -= l)
constexpr ll inf = (1ll << 62);
constexpr int N = 3e5 + 10;
template <typename T> void chkmax(T& a, T b) { a = max(a, b); }
template <typename T> void chkmin(T& a, T b) { a = min(a, b); }
int n, a[N], minn[N << 2];
ll tree[N << 2];
ll calc(int l, int r, int k, int p) {
if (minn[p] >= k) return 0ll;
if (l == r) return 1ll * l * (k - minn[p]);
int mid = l + r >> 1;
if (minn[p << 1] < k) return calc(l, mid, k, p << 1) + tree[p] - tree[p << 1];
return calc(mid + 1, r, k, p << 1 | 1);
}
void pushup(int l, int r, int p) {
int mid = l + r >> 1;
minn[p] = min(minn[p << 1], minn[p << 1 | 1]);
tree[p] = tree[p << 1] + calc(mid + 1, r, minn[p << 1], p << 1 | 1);
}
void build(int l, int r, int p) {
if (l == r) {
minn[p] = -1;
return;
}
int mid = l + r >> 1;
build(l, mid, p << 1);
build(mid + 1, r, p << 1 | 1);
pushup(l, r, p);
}
void update(int l, int r, int x, int k, int p) {
if (l == r) {
tree[p] = 0;
minn[p] = k;
return;
}
int mid = l + r >> 1;
if (x <= mid) update(l, mid, x, k, p << 1);
else update(mid + 1, r, x, k, p << 1 | 1);
pushup(l, r, p);
}
void solve() {
cin >> n;
rep(i, 0, n) {
cin >> a[i];
}
build(0, n, 1);
ll ans = 0;
rep(i, 0, n) {
if (a[i] <= n) {
update(0, n, a[i], i, 1);
}
ans += tree[1];
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
::::