题目大意
给出一个长度为
n
n
n的数组
a
1
,
a
2
,
⋯
,
a
n
a_1,a_2,\cdots,a_n
a1,a2,⋯,an,
问有多少个四元组
(
i
,
j
,
k
,
l
)
\pod{i,j,k,l}
(i,j,k,l)满足
i
<
j
<
k
<
l
,
a
i
=
a
k
,
a
j
=
a
l
i<j<k<l,a_i=a_k,a_j=a_l
i<j<k<l,ai=ak,aj=al
时间限制
2s
数据范围
a i ≤ n ≤ 3000 a_i\le n\le 3000 ai≤n≤3000
题解
显然枚举
i
,
k
i,k
i,k,然后统计在
(
i
,
k
)
\pod{i,k}
(i,k)中与
(
k
,
n
]
(k,n]
(k,n]中有多少对相同的。
不妨固定
i
i
i,向右移动
k
k
k。那么每次移动
k
k
k,就会有一个数加入
(
i
,
k
)
\pod{i,k}
(i,k)中,一个数离开
(
k
,
n
]
(k,n]
(k,n]中。注意这并不是同一个数。
因为 a i a_i ai不大,可以用桶来统计,每次累加答案即可。
Code
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#define G getchar
#define ll long long
using namespace std;
ll read()
{
char ch;
for(ch = G();(ch < '0' || ch > '9') && ch != '-';ch = G());
ll n = 0 , w;
if (ch == '-')
{
w = -1;
ch = G();
} else w = 1;
for(;'0' <= ch && ch <= '9';ch = G())n = (n<<1)+(n<<3)+ch-48;
return n * w;
}
const int N = 3003;
int n , a[N] , s[N] , t[N] , g[N];
ll ans , tmp;
int main()
{
//freopen("h.in","r",stdin);
//freopen("2.txt","w",stdout);
for (int T = read() ; T ; T--)
{
n = read();
memset(s , 0 , sizeof(s));
for (int i = 1 ; i <= n ; i++)
{
a[i] = read();
s[a[i]]++;
}
ans = 0;
for (int i = 1 ; i <= n ; i++)
{
s[a[i]]--;
memcpy(t , s , sizeof(t));
memset(g , 0 , sizeof(g));
tmp = 0;
for (int j = i + 1 ; j <= n ; j++)
{
tmp = tmp - g[a[j]];
t[a[j]]--;
if (a[i] == a[j]) ans = ans + tmp;
tmp = tmp + t[a[j]];
g[a[j]]++;
}
}
printf("%lld\n", ans);
}
return 0;
}