比赛 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;
}