刚看到到这题,在想是否可以二分答案,然而答案的可行性并不是单调的。
所以我设
l
为当前答案可能的最小值,在l=m+1
,否则不动,快要超时了就退出。
然后洛谷上居然AC了!
去bzoj上交一发,可能数据比较强,怎么调参也调不过。
#include<cstdio>
#include<ctime>
const int N=2000005;
int l,r,b[N],c[N],s[N],i,n,m,ss;
char a[N];
namespace GenHelper
{
unsigned z1,z2,z3,z4,b;
unsigned rand_()
{
b=((z1<<6)^z1)>>13;
z1=((z1&4294967294U)<<18)^b;
b=((z2<<2)^z2)>>27;
z2=((z2&4294967288U)<<2)^b;
b=((z3<<13)^z3)>>21;
z3=((z3&4294967280U)<<7)^b;
b=((z4<<3)^z4)>>12;
z4=((z4&4294967168U)<<13)^b;
return (z1^z2^z3^z4);
}
}
void srand(unsigned x)
{using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
int Rand()
{
using namespace GenHelper;
int a=rand_()&32767;
int b=rand_()&32767;
return a*32768+b;
}
int main(){
scanf("%d%s",&n,a+1);
srand(19260817);//主席赐予我力量!
for(i=1;i<=n;++i)b[i]=b[i-1]+(a[i]=='B'),c[i]=c[i-1]+(a[i]=='C'),s[i]=s[i-1]+(a[i]=='S');
for(l=1,r=n;l<r && ss<2100000000;){
m=Rand()%(r-l)+l+1;
for(i=m;i<=n;++i)
if(((b[i]==b[i-m] || c[i]==c[i-m]) && s[i]==s[i-m]) || (b[i]==b[i-m] && c[i]==c[i-m]) ||
(b[i]-b[i-m]!=c[i]-c[i-m] && c[i]-c[i-m]!=s[i]-s[i-m] && s[i]-s[i-m]!=b[i]-b[i-m]))
break;
ss+=m;
if(i<=n)l=m;
}
printf("%d\n",l);
return 0;
}