比赛 |
20160414 |
评测结果 |
WWWWWWEEEE |
题目名称 |
随机数消除器 |
最终得分 |
0 |
用户昵称 |
mikumikumi |
运行时间 |
1.756 s |
代码语言 |
C++ |
内存使用 |
92.63 MiB |
提交时间 |
2016-04-14 17:12:38 |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int SIZEN=800010;
int N;
int text[SIZEN];
int SA[SIZEN],rank[SIZEN],height[SIZEN];
char str[SIZEN];
int tot=0;
void read()
{
scanf("%s",str);
N=strlen(str);
for(int i=0;i<N;i++) text[i]=str[i]-'a';
text[N]=3;
for(int i=1,j=N;i<=N;i++,j--) text[i+N]=str[j-1]-'a';
tot=N*2;
text[tot+1]=9;
}
int sum[SIZEN];
int A[SIZEN],B[SIZEN];
int x[SIZEN],y[SIZEN];
void basesort(int a[],int b[],int c[],int n,int m)
{
for(int i=0;i<=m;i++) sum[i]=0;
for(int i=0;i<n;i++) sum[b[a[i]]]++;
for(int i=1;i<=m;i++) sum[i]+=sum[i-1];
for(int i=n-1;i>=0;i--) c[--sum[b[a[i]]]]=a[i];
}
void sortsuf(int text[],int SA[],int rank[],int n)
{
for(int i=0;i<n;i++) A[i]=i,x[i]=text[i];
basesort(A,x,SA,n,4);
rank[SA[0]]=1;
for(int i=1;i<n;i++)
{
if(x[SA[i]]==x[SA[i-1]]) rank[SA[i]]=rank[SA[i-1]];
else rank[SA[i]]=rank[SA[i-1]]+1;
}
for(int k=1;k<=n;k<<=1)
{
for(int i=0;i<n;i++)
{
A[i]=i;
x[i]=rank[i];
if(i+k<n) y[i]=rank[i+k];
else y[i]=0;
}
basesort(A,y,B,n,n);
basesort(B,x,SA,n,n);
rank[SA[0]]=1;
for(int i=1;i<n;i++)
{
if(x[SA[i]]==x[SA[i-1]]&&y[SA[i]]==y[SA[i-1]]) rank[SA[i]]=rank[SA[i-1]];
else rank[SA[i]]=rank[SA[i-1]]+1;
}
}
for(int i=0;i<n;i++) rank[SA[i]]=i;
}
void make_height(int n)
{
int h=0;
for(int i=0;i<=n;i++)
{
if(rank[i]==0) h=0;
else
{
int k=SA[rank[i]-1];
if(--h<0) h=0;
while(text[i+h]==text[k+h]) h++;
}
height[rank[i]]=h;
}
}
int Log[SIZEN];
int ST[SIZEN][20];
void Log_prepare()
{
for(int i=1,k=0;i<=tot+1;i<<=1,k++)
{
for(int j=i;j<i*2;j++) Log[j]=k;
}
}
void ST_prepare()
{
for(int i=0;i<=tot;i++) ST[i][0]=i;
int m=Log[tot+1];
for(int j=1;j<=m;j++)
{
for(int i=0;i<=tot;i++)
{
if(i+(1<<j)-1>tot) break;
if(height[ST[i][j-1]]<height[ST[i+(1<<(j-1))][j-1]]) ST[i][j]=ST[i][j-1];
else ST[i][j]=ST[i+(1<<(j-1))][j-1];
}
}
}
int RMQ(int l,int r)
{
int m=Log[r-l+1];
if(height[ST[l][m]]<height[ST[r-(1<<m)+1][m]]) return height[ST[l][m]];
return height[ST[r-(1<<m)+1][m]];
}
void work()
{
sortsuf(text,SA,rank,tot+1);
make_height(tot);
Log_prepare();
ST_prepare();
int ans=0,cnt=0;
for(int i=1;i<tot;i++)
{
if(cnt>height[i]) cnt=height[i];
if(SA[i]<N)
{
int other=2*N-SA[i];
int tem=RMQ(min(i,rank[other])+1,max(i,rank[other]));
if(tem>cnt)
{
cout<<SA[i]<<" "<<rank[other]<<" "<<tem<<" "<<cnt<<endl;
ans+=(tem-cnt);
cnt=tem;
}
}
}
cnt=0;
for(int i=1;i<tot;i++)
{
if(cnt>height[i]) cnt=height[i];
if(!SA[i]) continue;
if(SA[i]<N)
{
int other=2*N-SA[i]+1;
int tem=RMQ(min(i,rank[other])+1,max(i,rank[other]));
if(tem>cnt)
{
ans+=(tem-cnt);
cnt=tem;
}
}
}
printf("%d\n",ans);
}
int main()
{
freopen("randomb.in","r",stdin);
freopen("randomb.out","w",stdout);
read();
work();
return 0;
}