【CF1527C】Sequence Pair Weight

发布时间 2023-09-09 09:16:41作者: Alric

题目大意:

给出一个长度为\(n(1\le n\le 10^{5})\)的序列\(a_1,a_2,...,a_n\),计算\(\sum_{1\le l<r\le n}\sum_{l\le i<j\le r}[a_i=a_j]\)


\(\sum_{1\le l<r\le n}\sum_{l\le i<j\le r}[a_i=a_j]=\)

\(\sum_{1\le i<j\le n}[a_i=a_j]\times i\times(n-j+1)=\)

\(\sum_{j=1}^{n}\{(n-j+1)\times \sum_{1\le i<j}[a_i=a_j]\times i\}=\)

\(\sum_{x}\sum_{a_j=x}\{(n-j+1)\times \sum_{1\le i<j,a_i=x}i\}\)

对于每种不同的数开一个vector,将其位置从小到大储存在其对应的vector中。\(\sum_{1\le i<j,a_i=x}i\)的值可以通过前缀和求得。枚举\(x\)\(j\)的值,即可计算出题目的答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a[100000+10];
vector<ll> dct,pos[100000+10];
ll query(ll x){
	return lower_bound(dct.begin(),dct.end(),x)-dct.begin()+1;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int T;
	cin >> T;
	while(T--){
		ll ans=0;
		cin >> n;
		dct.clear();
		for(ll i=1;i<=n;i++)pos[i].clear();
		for(ll i=1;i<=n;i++)cin >> a[i],dct.push_back(a[i]);
		sort(dct.begin(),dct.end());
		dct.erase(unique(dct.begin(),dct.end()),dct.end());
		for(ll i=1;i<=n;i++)pos[query(a[i])].push_back(i);
		for(ll i=1;i<=dct.size();i++){
			ll pre=0;
			for(ll j=0;j<pos[i].size();j++){
				ans+=pre*(n-pos[i][j]+1);
				pre+=pos[i][j];
			}
		}
		cout << ans << endl;
	}
	return 0;
}