CF1479B1 Painting the Array I

神仙贪心题。

假设当前末尾两数分别为 (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;
}
原文地址:https://www.cnblogs.com/May-2nd/p/14414784.html