解题报告:写这种题还是暴力香,虽然我也没有想到,现在懂了,然后二维前缀和可以不用memset,就因为这个tle的,这题做法就是维护前缀和(每个数在某段区间出现的个数)因为总共就200个数,然后把各个数的位置push进vector,每次对称着取两个位置加上中间的前缀和之差不断更新ans,就能解决这题啦!
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#define IL inline
#define x first
#define y second
typedef long long ll;
using namespace std;
const int N = 210;
const int M = 200010;
int sum[N][M];
int n;
int a[M];
int main()
{
ios::sync_with_stdio(false);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
vector<int>v[N];
cin >> n;
for(int i = 1; i <= n ;i++)
{
cin >> a[i];
v[a[i]].push_back(i);
}
int ans = 1;
for(int i = 1;i <= 200; i++)
for(int j = 1;j <= n; j++)
sum[i][j] = sum[i][j-1] + (a[j] == i);
//exit(0);
for(int i=1 ; i <=200 ;i++)
for(int j=0;j < v[i].size()/2;j++)
{
// cout << j<<' ' << v[i].size()-1-j<<endl;
int pos1 = v[i][j] , pos2 = v[i][v[i].size()-1-j];
for(int k=1;k<=200;k++)
ans = max(ans,(j+1)*2 + sum[k][pos2-1]-sum[k][pos1]);
}
cout << ans << endl;
}
return 0;
}