这道题的easy版本我写的是n^2*26的,对于这题显然不够用。
我们发现上一题我们遍历了很多重复的情况,因为我们是按位置进行遍历的,所以要全部遍历,这次我们优化一下
我们发现个数最多只有200,因此我们按这个作为枚举对象。进一步发现,因为我们枚举的是a这些数作为两边
那么对于每个数,只需要找到他在哪些地方出现过,就能作为枚举的边界
因此存一个vector来代表他的出现位置,之后中间这段同样枚举200次,这样复杂度就比较优秀了
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; const int mod=1e9+7; int s[N][210]; int a[N]; vector<int> num[210]; int main(){ int t; cin>>t; while(t--){ int n; for(int i=0;i<210;i++) num[i].clear(); cin>>n; int i,j; for(i=1;i<=n;i++){ cin>>a[i]; num[a[i]].push_back(i); for(j=1;j<=200;j++) s[i][j]=s[i-1][j]; s[i][a[i]]++; } int l,r; int ans=0; for(i=1;i<=200;i++) ans=max(ans,s[n][i]); for(i=1;i<=200;i++){ int cnt1=0; int si=(int)num[i].size(); if(si==1) continue; for(j=0;j<si/2;j++){ int l=num[i][j]; int r=num[i][si-j-1]; cnt1=(j+1)*2; for(int k=1;k<=200;k++){ ans=max(ans,cnt1+s[r-1][k]-s[l][k]); } } } cout<<ans<<endl; } }