28pts求调,玄关
查看原帖
28pts求调,玄关
700558
williamwei楼主2025/7/24 10:57
#include <iostream>
#include <set>
using namespace std;
#define int long long
#define A(x) ((x) * (x))
const int maxn = 1e5 + 10;
const int maxm = 1e4 + 10;
int n, cl, cr, a[maxn], f[maxn], cnt[maxm];
set<int> se;
void add(int x) {if (!a[x]) return; se.erase(a[x] * A(cnt[a[x]])); ++cnt[a[x]]; se.insert(a[x] * A(cnt[a[x]]));}
void del(int x) {if (!a[x]) return; se.erase(a[x] * A(cnt[a[x]])); --cnt[a[x]]; se.insert(a[x] * A(cnt[a[x]]));}
void val(int L, int R) {
	while (cl > L) add(--cl); while (cr < R) add(++cr);
	while (cl < L) del(cl++); while (cr > R) del(cr--);
}
void solve(int l, int r, int L, int R) {
    int mid = (l + r) >> 1, mx = -1, p;
    for (int i = L; i <= min(R, mid); i++) {
        val(i, mid); int w = f[i - 1] + *se.rbegin();
        if (w > mx) mx = w, p = i;
    } f[mid] = mx; if (l == r) return;
    solve(l, mid, L, p); solve(mid + 1, r, p, R);
}
signed main() {
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    solve(1, n, 1, n); cout << f[n] << '\n';
    return 0;
}
2025/7/24 10:57
加载中...