二分写while(j<=h)过不了
查看原帖
二分写while(j<=h)过不了
617078
zhouyuxuan3501楼主2024/7/20 20:10

二分中的变量z记录了LCP的长度,但是两种写法分别WA了1和两个点,求调。

95分代码

#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;
}

90分代码

#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;
}
2024/7/20 20:10
加载中...