cf#634dic3 E2. Three Blocks Palindrome (hard version)

 题解:维护一个前缀和,枚举两侧用的字母和中间用的字母,两侧长度

看起来复杂度是O(nk^2)但实际是O(nk),我也不知道为什么

注意本题要使用vector节约内存 否则会mle

下标最好从0开始否则会出现奇奇怪怪不可名状的错误

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200001
#define inf 1e9+7
int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}
int a[N];
int main()
{
    int t=read();
    while(t--) 
    {
        memset(a,0,sizeof(a));
        int n=read();
        vector<vector<int> >pos(201);
        vector<vector<int> >pre(201,vector<int>(n+1));
        for(int i=0;i<n;i++)
        {
            a[i]=read();
            for(int j=0;j<200;j++)
            pre[j][i+1]=pre[j][i];
            pre[a[i]-1][i+1]++;
            pos[a[i]-1].push_back(i);
        }
        int maxx=0;
        for(int i=0;i<200;i++)
        {
            maxx=max(maxx,(int)pos[i].size());
            for(int j=0;j<pos[i].size()/2;j++)
            {
                int l=pos[i][j]+1;
                int r=pos[i][pos[i].size()-j-1]-1;
                for(int k=1;k<=200;k++)
                {
                    maxx=max(maxx,pre[k][r+1]-pre[k][l]+2*j+2);
                }
            }
        }
        cout<<maxx<<endl;
    }
}
View Code

猜你喜欢

转载自www.cnblogs.com/curezero233/p/12724501.html