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;
}