思路:
因为每个数比较小,可以从这里切入,开始想的是枚举中间那部分,但是中间固定了2边不好确定,因为2边要一样,所以我们可以固定2边,然后对于中间位置,只需找出出现次数最多的数,前缀和预处理一下。枚举第i个数,前面num个数,然后二分查找后面num个数的位置。
code
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
typedef long long ll;
const ll mod = 1e9+7;
int pre[205][man];
int a[man];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n;
int t;
cin >> t;
while(t--){
cin >> n;
for(int i = 1;i <= n;i++){
cin >> a[i];
for(int j = 1;j <= 200;j++){
pre[j][i] = pre[j][i-1] + (a[i]==j);
}
}
int ans = 0;
for(int i = 1;i <= n;i++){
int num = pre[a[i]][i];
int total = pre[a[i]][n];
ans = max(ans,total);
int l = i,r = n;
int res = -1;
while(l<=r){
int mid = (l + r ) >> 1;
if(total - pre[a[i]][mid] >= num){
res = mid;
l = mid + 1;
}else r = mid - 1;
}
//cout << res << endl;
if(res==-1)continue;
for(int j = 1;j <= 200;j++){
ans = max(ans,2 * num + pre[j][res] - pre[j][i]);
}
}
cout << ans << endl;
}
return 0;
}