CF1335E2-Three Blocks Palindrome (hard version) (二分+双指针)

题目大意:

题意就是告诉你一个数n,然后给你n个数,每个数满足1<=a[i]<=200,让你求最大的子序列,子序列由x个a和y个b和x个a构成。

链接:https://codeforces.com/contest/1335/problem/E2

思路:

我们先用一个vector v记录1-200中每个数出现的位置,这里以1为例,v[1]中记录的是1这个数出现的所有位置,

然后我们用两个指针l(指向v[1]中的第一个数)和r(指向v[1]中的最后一个数),此时x=1,我们不难发现,1-200中的每个数,

只要出现在v[1][l]和v[1][r]之间均能满足所给条件,然后l++,r--,x++(x代表左边有x个1,右边有x个1),然后继续寻找,

不断的取最大值即可。复杂度为n*n*log(n),呸,转头一想好像不是这个复杂度(因为还要算上双指针移动,菜逼不知道咋算,

当时就想着试试感觉能过然后就过了),因为a[i]的最大值为200(即n的上限为200),所以能跑过去,不过好像是刚刚水过去。

可能我表述的有些混乱,看了代码应该可以稍微清晰一点。

代码:

#include <bits/stdc++.h>
#define Pair pair<int,int>
using namespace std;
typedef long long ll;
const int MAXN=5e5+5;
const int INF=1e9;
int a[MAXN];
vector<int>v[300];
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);
    int t;cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1; i<=200; i++)
            v[i].clear();
        for(int i=1; i<=n; i++)
        {
            cin>>a[i];
            v[a[i]].push_back(i);   //记录每个a[i]出现的位置
        }
        int max_=1;
        for(int i=1; i<=200; i++)
        {
            int ans=0;
            int l=0,r=v[i].size()-1;
            while(l<r)
            {
                //printf("%d %d %d\n",i,l,r);
                int item1=v[i][l],item2=v[i][r];
                //printf("%d %d\n",item1,item2);
                ans+=2;     //因为子序列左边添了一个,右边添了一个,所以此时子序列的长度加2
                for(int j=1; j<=200; j++)
                {
                    if(v[j].empty())
                        continue;
                    if(j==i)
                    {
                        max_=max(max_,(int)v[i].size());
                        continue;
                    }
                    int index1=upper_bound(v[j].begin(),v[j].end(),item1)-v[j].begin();
                    int index2=upper_bound(v[j].begin(),v[j].end(),item2)-v[j].begin()-1;
                    //index2-index1+1为中间的数的个数,ans+index2-index1+1即为子序列的大小
                    max_=max(max_,ans+index2-index1+1);
                }
                l++;r--;
            }
        }
        printf("%d\n",max_);
    }


    return 0;
}

 

posted @ 2020-04-14 18:42  grass_lin  阅读(243)  评论(2编辑  收藏  举报