二分中的变量z记录了LCP的长度,但是两种写法分别WA了1和两个点,求调。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define L long long
#define B 307
#define P 50000017
#define HASH(a,b) (hash[b]-hash[a-1]*Mn[b-a+1]%P+P)%P
using namespace std;
char c[300003];
int l,SA[300003];
L hash[300003],Mn[300003];
int erfen(int a,int b)
{
int j=0,h=min(l-a,l-b)+1,m,z=0;
while(j<=h)
{
m=(j+h)>>1;
if(HASH(a,a+m)==HASH(b,b+m))
{
z=m;
j=m+1;
}
else h=m-1;
}
while(c[a+z]==c[b+z]&&a+z<l&&b+z<l)z++;
return z;
}
bool A(int a,int b)
{
int h=erfen(a,b);
return c[a+h]<c[b+h];
}
int main()
{
int i;
scanf("%s",c+1);
l=strlen(c+1)+1;
c[l]='*';
Mn[0]=1;
for(i=1;i<=l;i++)
{
SA[i]=i;
Mn[i]=Mn[i-1]*B%P;
hash[i]=(hash[i-1]*B+c[i])%P;
}
sort(SA+1,SA+l,A);
for(i=1;i<l;i++)printf("%d ",SA[i]-1);
printf("\n0 ");
for(i=2;i<l;i++)printf("%d ",erfen(SA[i],SA[i-1]));
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cstring>
#define L long long
#define B 307
#define P 50000017
#define HASH(a,b) (hash[b]-hash[a-1]*Mn[b-a+1]%P+P)%P
using namespace std;
char c[300003];
int l,SA[300003];
L hash[300003],Mn[300003];
int erfen(int a,int b)
{
int j=0,h=min(l-a+1,l-b+1)+1,m,z=0;
while(j<=h)
{
m=(j+h)>>1;
if(HASH(a,a+m)==HASH(b,b+m))
{
j=m+1;
z=m+1;
}
else h=m-1;
}
return z;
}
bool A(int a,int b)
{
int h=erfen(a,b);
return c[a+h]<c[b+h];
}
int main()
{
int i;
scanf("%s",c+1);
l=strlen(c+1)+1;
c[l]='*';
Mn[0]=1;
for(i=1;i<=l;i++)
{
SA[i]=i;
Mn[i]=Mn[i-1]*B%P;
hash[i]=(hash[i-1]*B+c[i])%P;
}
sort(SA+1,SA+l,A);
for(i=1;i<l;i++)printf("%d ",SA[i]-1);
printf("\n0 ");
for(i=2;i<l;i++)printf("%d ",erfen(SA[i],SA[i-1]));
return 0;
}