题目大意:就是给你 i < j < k < l 并 且 a j = a l & & a i = a k i<j<k<l并且a_j=a_l \&\& a_i=a_k i<j<k<l并且aj=al&&ai=ak,求满足(i,j,k,l)的四元组有多少对
解题思路:1.很明显我们最暴力的做法是
O
(
n
4
)
O(n^4)
O(n4)去枚举,因为题目的数据只有3000,可以预估的复杂度在
O
(
n
2
)
O(n^2)
O(n2)左右,那么实际上我们可以只枚举i,
j,k,l其中两个
2.我们可以枚举k和i,注意是k和i就是先枚举k再逆序去枚举i,接下来就是如何把j和l统计进去
3.根据乘法原理每个总数就是
s
u
m
j
∗
s
u
m
l
sum_j*sum_l
sumj∗suml,但是是每一个k和i都要跑一遍吗?不用.用dp的思想,设dp[i][j],就是从j到i满足条件的四元组的个数,dp[k][i]其实可以用dp[k][i+1]的基础上加上了a[i]这个数在[k,n]这个区间内和它相同的数的个数
那么对于每个k我们预处理[k,n]每个数出现的次数然后按照上面的思路转移就好了
void solve(){
ll ans=0,sum;//统计所有次数。
rep(i,1,n){
//我们确定第三个编号,统计第四个编号出现的次数。
sum=0;
memset(cnt,0,sizeof(cnt));//初始化。
rep(j,i+1,n)cnt[a[j]]++;//统计第三个编号之后每个元素出现次数
per(j,i-1,1){
if(a[j]==a[i]){
//说明找到第一个编号,我们统计之间有多少的方案数。
ans+=sum;
}
sum+=cnt[a[j]];//统计第二个编号的方案数。
}
}
cout<<ans<<endl;
}