Avin is studying series. A series is called “wave” if the following conditions are satisfied:
- It contains at least two elements;
- All elements at odd positions are the same;
- All elements at even positions are the same;
- Elements at odd positions are NOT the same as the elements at even positions.
You are given a series with length n. Avin asks you to find the longest “wave” subseries. A subseries is a subsequence of a series.
InputThe first line contains two numbers n, c (1 ≤ n ≤ 100, 000, 1 ≤ c ≤ 100). The second line contains n integers whose range is [1, c], which represents the series. It is guaranteed that there is always a “wave” subseries.
OutputPrint the length of the longest “wave” subseries.
Sample Input
5 3
1 2 1 3 2
Sample Output
4
题意:
题目给你一个序列,找一个波的最大长度,波定义为:
1)它包含至少两个元素;
2)奇数位置的所有元素都是相同的;
3)偶数位置的所有元素都是相同的;
4)奇数位置的元素与偶数位置的元素不同
这个题比赛时亨亨写了一发优化暴力直接a了,后来听学长讲解,第一次听到序列自动机这个高bi格的东西,即一个二维的数组next [i][j],表示在数i的第j个的位置,然后枚举奇偶两个位置,保存最大值;
预处理:
for(int i=1;i<=n;i++)
{
ll k;
scanf("%lld",&k);
a[k].push_back(i); //将输入的每个数的位置保存下来,之后就可以遍历奇数和偶数的位置;
}
遍历
for(int i=1;i<=c;i++)
{
for(int j=1;j<=c;j++)
{
if(i==j) continue;
ll num=0;
ll s1=a[i].size(),s2=a[j].size();
//printf("%d: %lld %d: %lld\n",i,s1,j,s2);
ll k=0,p=0,q=0;
while(1)
{
while(p<s1&&k>a[i][p]) //遍历奇数
//用k记录上一个遍历的位置,下一个位置要>K才行;
p++;
if(p==s1)
break;
num++;
k=a[i][p];
while(q<s2&&k>a[j][q]) //遍历偶数
q++;
if(q==s2)
break;
k=a[j][q];
num++;
}
ans=max(ans,num);
//printf("%lld\n",ans);
}
}
代码
#include<bits/stdc++.h>
#include<map>
#define ll long long
using namespace std;
const int maxn=1e5+7;
const int INF=1e9;
vector<ll >a[105];
int main()
{
ll n,c;
scanf("%lld%lld",&n,&c);
for(int i=1;i<=n;i++)
{
ll k;
scanf("%lld",&k);
a[k].push_back(i);
}
/*for(int i=1;i<=c;i++)
{
printf("%d: ",i);
for(int j=0;j<a[i].size();j++)
printf("%lld ",a[i][j]);
printf("\n");
}*/
ll ans=0;
for(int i=1;i<=c;i++)
{
for(int j=1;j<=c;j++)
{
if(i==j) continue;
ll num=0;
ll s1=a[i].size(),s2=a[j].size();
//printf("%d: %lld %d: %lld\n",i,s1,j,s2);
ll k=0,p=0,q=0;
while(1)
{
while(p<s1&&k>a[i][p]) //奇数
p++;
if(p==s1)
break;
num++;
k=a[i][p];
while(q<s2&&k>a[j][q]) //偶数
q++;
if(q==s2)
break;
k=a[j][q];
num++;
}
ans=max(ans,num);
//printf("%lld\n",ans);
}
}
printf("%lld\n",ans);
return 0;
}