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;
}

浙公网安备 33010602011771号