由伪代码可知某个数的贡献会受它前一次出现的位置影响,当子数组包含上一次出现的这个数时,此时该位置该数不算贡献,所以要开个last映射它上一次的位置,计算以当前位置结尾的所有子数组中当前位置的贡献时减去last即可。
附本人ac码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define mod 998244353
const ll N=1e6+10;
ll a[N],pre[N],cnt[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin>>t;
while(t--)
{
map<int,int>last;
ll n;
cin>>n;
ll sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
cnt[i]=cnt[i-1]+i-last[a[i]];
last[a[i]]=i;
pre[i]=pre[i-1]+cnt[i];
sum+=pre[i];
}
cout<<sum<<endl;
}
return 0;
}

京公网安备 11010502036488号