题目链接:codeforces 1400 D. Zigzags
题意:
给定一个长度为 n 的序列 a (n≤3000,ai≤n),求有多少个四元组 (i,j,k,l) 满足:
- 1 ≤ i < j < k < l ≤n
- a[i] = a[k] 且 a[j] = a[l]
解题思路:
4层for循环跑必然超时,所以需要优化,跑两层for循环,使用前缀和记录当前数字在 当前位置之前出现多少次
具体为什么:点击查看
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3005;
long long ans;
int sum[maxn][maxn], n, a[maxn];
int main(){
int t;
cin >> t;
while(t--) {
ans = 0;
sum[0][0] = 0; sum[0][1] = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
for(int j = 1; j <= n; j++) {
sum[i][j] = sum[i-1][j];
}
sum[i][a[i]]++;
}
for(int j = 2; j <= n; j++) {
for(int k = j+1; k < n; k++) {
ans = ans + (sum[j-1][a[k]]) * (sum[n][a[j]]-sum[k][a[j]]);
// sum[j-1][a[k]] 表示a[k]这个数字在j-1之前出现多少次
// sum[n][a[j]-sum[k][a[j]] 表示 a[j]这个数字在k之后出现多少次
}
}
cout << ans <<endl;
}
return 0;
}