CF1848B Vika and the Bridge
LimpidSlirm · · 题解
题意
给定一个序列,从
Solution
赛时一眼二分,然后写着写着发现根本没必要二分,因为只有一次改变颜色的机会。
贪心地去求答案,对于每一种颜色记录两个点之间的距离的最大值和次大值,然后把最大值的那段区间的中点颜色更改成当前颜色。令最大值为
记得处理到终点即第
时间复杂度为
code
#include<bits/stdc++.h>
inline int read()
{
long long res=0,flag=1;
char ch=getchar();
while(!isalnum(ch)) (ch=='-')?flag=-1:1,ch=getchar();
while(isalnum(ch)) res=res*10+ch-'0',ch=getchar();
return res*flag;
}
int val[200010];
int ans[200010][3];
void solve()
{
int n=read(),k=read(),res=0x3f3f3f3f;
memset(ans,0,sizeof ans);
for(int i=1;i<=n;i++)
val[i]=read();
for(int i=1;i<=n;i++)
{
if(i-ans[val[i]][0]>=ans[val[i]][1])
std::swap(ans[val[i]][1],ans[val[i]][2]),ans[val[i]][1]=i-ans[val[i]][0];
else if(i-ans[val[i]][0]>=ans[val[i]][2])
ans[val[i]][2]=i-ans[val[i]][0];
ans[val[i]][0]=i;
}
for(int i=1;i<=k;i++)
{
if(n+1-ans[i][0]>=ans[i][1])
std::swap(ans[i][1],ans[i][2]),ans[i][1]=n+1-ans[i][0];
else if(n+1-ans[i][0]>=ans[i][2])
ans[i][2]=n+1-ans[i][0];
ans[i][1]--,ans[i][2]--;
// std::cout<<i<<" "<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<std::endl;
res=std::min(res,std::max((int)(ans[i][1]/2),ans[i][2]));
}
printf("%d\n",res);
return ;
}
int main(int argc,const char *argv[])
{
int T=read();
while(T--)
solve();
return 0;
}