神仙贪心题。
假设当前末尾两数分别为 (a,b),现在新进来一个数 (c):
- (a=b),没什么好说的,随便拿一个换掉。
- (a=c eq b),因为有贡献所以肯定换 (b)。
- (b=c eq a),同理。
- (a eq c,b eq c,a eq b),选择下次出现位置更近的换。
B2 就把最近改成最远就好了。
正确性就考虑可以换回来嘛。官方题解一大坨我也看不懂。
时间复杂度 (O(n))。
code:
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define For(i,x,y)for(i=x;i<=(y);i++)
#define Down(i,x,y)for(i=x;i>=(y);i--)
int a[N],pos[N],nxt[N];
int main()
{
int n,i,x,y,s;
s=x=y=0;
scanf("%d",&n);
For(i,1,n)scanf("%d",&a[i]);
nxt[0]=n+2;
For(i,1,n)pos[a[i]]=n+1;
Down(i,n,1)nxt[i]=pos[a[i]],pos[a[i]]=i;
For(i,1,n)
{
if(a[i]!=a[x]&&a[i]!=a[y])if(nxt[x]<nxt[y])x=i;
else y=i;
else if(a[i]!=a[x])x=i;
else if(a[i]!=a[y])y=i;
else x=y=i,s++;
/*printf("%d %d
",x,y);*/
}
printf("%d",n-s);
return 0;
}