CF1883F 题解

注意到如下结论:区间 \([l, r]\) 满足题目条件当且仅当 \(a_l\) 第一次出现,且 \(a_r\) 最后一次出现。

证明:充分性显然,下面证明必要性。

若区间 \([l, r]\) 不满足上述条件,则我们可以找到在 \(a_l\) 左边与其相同的数与 \([l + 1, r]\) 拼起来,或找到在 \(a_r\) 右边与其相同的数与 \([l, r - 1]\) 拼起来。

故该区间不满足题目条件。

所以对于下标 \(i\),我们维护 \(f_i, l_i\) 分别记录 \(a_i\) 是否是第一个与最后一个出现的。若 \(a_i\) 是第一个出现的,则 \(f_i = 1\);否则 \(f_i = 0\)\(l_i\) 同理。

\(S_i = \sum \limits_{j = i}^n l_j\),则答案为

\[\sum_{i = 1}^n f_i \cdot S_i \]

#include <iostream>
#include <map>
#include <vector>

using namespace std;
using i64 = long long;

void solve_test()
{
    int n;
    cin >> n;

    vector<int> arr(n);
    vector<bool> fst(n), lst(n);
    map<int, bool> vis;

    for (int i = 0; i < n; ++i) {
        cin >> arr[i];

        if (!vis[arr[i]])
            vis[arr[i]] = fst[i] = true;
    }

    decltype(vis)().swap(vis);

    for (int i = n - 1; i >= 0; --i) {
        if (!vis[arr[i]])
            vis[arr[i]] = lst[i] = true;
    }

    vector<int> suff(n, lst[n - 1]);

    for (int i = n - 2; i >= 0; --i)
        suff[i] = suff[i + 1] + (int)lst[i];

    i64 ans = 0;

    for (int i = 0; i < n; ++i)
        ans += (i64)fst[i] * suff[i];

    cout << ans << '\n';
}

int main()
{
    int t;
    cin >> t;

    while (t-- > 0)
        solve_test();

    return 0;
}
posted @ 2025-08-02 16:11  David9006  阅读(7)  评论(0)    收藏  举报