Zigzags
We can rethink this as counting the number of equal pairs
(
a
i
,
a
j
)
=
(
a
k
,
a
l
)
(a_i, a_j) = (a_k, a_l)
(ai,aj)=(ak,al) where
i
<
j
<
k
<
l
i < j < k < l
i<j<k<l. To do this we loop over
j
j
j from right to left and make sure we have all
(
a
k
,
a
l
)
(a_k, a_l)
(ak,al) pairs where
k
>
j
k > j
k>j counted in a map. Then we simply iterate over
i
i
i and add up the number of occurrences of each
(
a
i
,
a
j
)
(a_i, a_j)
(ai,aj) in the map.
For implementation details, note that we don’t actually want to use a map and make our code slower. We can just use an array of size n 2 n^2 n2 and convert the pair ( a i , a j ) (a_i, a_j) (ai,aj) to the number a i ⋅ n + a j a_i \cdot n + a_j ai⋅n+aj since the a i a_i ai are in the range [ 1 , n ] [1, n] [1,n]. As a bonus, even if the a i a_i ai were larger than n n n, we could just compress them down to [ 1 , n ] [1, n] [1,n] and repeat the solution above.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e3+10;
int n;
void solve() {
ll ans = 0;
scanf("%d", &n);
vector<int> a(n);
for (auto &i:a) {
scanf("%d", &i);
}
vector<int> b(n * (n + 1) + 10, 0);
for (int j = n - 1; j >= 0; j--) {
int k = j + 1;
for (int l = k + 1; l < n; l++) {
b[a[k] * n + a[l]]++;
}
for (int i = j - 1; i >= 0; i--) {
ans += b[a[i] * n + a[j]];
}
}
printf("%lld\n", ans);
}
int main() {
int _;
scanf("%d", &_);
while (_--) {
solve();
}
}