萌新求调后缀数组
查看原帖
萌新求调后缀数组
716965
L_zaa_L楼主2024/6/21 11:10
#include<bits/stdc++.h>
#define int long long
#define ls(x) ((x)*2)
#define rs(x) ((x)*2+1)
#define Debug(...) fprintf(stderr, __VA_ARGS__)
#define For(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define Rof(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define rep(i,  b) for(int i=1,i##end=b;i<=i##end;i++)
using namespace std;
const int N=1e6+5,Mod=998244353;
//char buf[(1<<21)+5],*p1,*p2;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
void chmx(int &x,int y){(x<y)&&(x=y);}
void chmn(int &x,int y){(x>y)&&(x=y);}
typedef __int128_t i128;
i128 _base=1;
inline int mol(int x){return x-Mod*(_base*x>>64);}
inline void Add(int &x,int y){x=mol(x+y+Mod);}
inline int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return f?-x:x;
}
int n,m=500;
int rak[N],tp[N],tag[N],sa[N];
int height[N]; 
char s[N];
inline void SA(){
	m=500;
	for(int i=0;i<=m;++i) tag[i]=0;
	for(int i=1;i<=n;++i) rak[i]=(int)s[i],tp[i]=sa[i]=height[i]=0;
	int p=0;
	for(int i=1;i<=n;++i)++tag[rak[i]];
	for(int i=1;i<=m;++i) tag[i]+=tag[i-1];
	for(int i=n;i>=1;--i) sa[tag[rak[i]]--]=i;
	//Radix_sort();
	for(int k=1;k<=n;k<<=1){
		p=0;
		for(int i=0;i<=m;++i) tag[i]=tp[i]=0;
		for(int i=n-k+1;i<=n;++i) tp[++p]=i;
		for(int i=1;i<=n;++i)
			if(sa[i]>k)
				tp[++p]=sa[i]-k;
		for(int i=1;i<=m;++i) tag[i]=0;
		for(int i=1;i<=n;++i)tag[rak[i]]++;
		for(int i=1;i<=m;++i) tag[i]+=tag[i-1];
		for(int i=n;i>=1;--i) sa[tag[rak[tp[i]]]--]=tp[i],tp[i]=0;
		swap(rak,tp);
		rak[sa[1]]=1;
		p=1;
		for(int i=2;i<=n;++i)
			rak[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+k]==tp[sa[i]+k])?p:++p;
		if(p>=n) break;
		m=p;
	}
}
void GetHeight() {
	height[0]=height[n+1]=-1e16;
	int k=0;
	for(int i=1;i<=n;++i) {
		if(k) --k;
		while(s[i+k]==s[sa[rak[i]-1]+k]) ++k;
		height[rak[i]]=k;
	}
}
int minsum[N][22];
inline void RMQ(int num){ 
	for(register int i=1;i<=n;i++) minsum[i][0]=height[i]; 
	for(register int j=1;j<=20;++j)
		for(register int i=1;i<=num&&i+(1<<j)-1<=num;++i){ 
				minsum[i][j]=min(minsum[i][j-1], minsum[i+(1<<(j-1))][j-1]);
			}
}//min(minsum[l][k],minsum[r-(1<<k)+1][k]);k=log2(r-l+1);
inline int rmq(int l,int r){
	int x=rak[l],y=rak[r];
	if(x>y) swap(x,y);
	x+=1;
	int k=log2(y-x+1);
	return min(minsum[x][k],minsum[y-(1<<k)+1][k]);
}    
char S[N],t[N];
int be[N];
signed main(){
	_base=(_base<<64)/Mod;
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>S;
	int len=strlen(S);
	int p=0;
	For(i,0,len-1)s[++p]=S[i];
	s[++p]=1;
	int q=read();
	For(i,1,q){
		cin>>t;
		int gg=strlen(t);
		be[i]=p+1;
		For(j,0,gg-1){
			s[++p]=t[j];
		}
		s[++p]=i+1;
	}
	be[q+1]=p+1;
	n=p;
	SA();GetHeight();RMQ(n);
	set<int>ss;
	For(i,1,len)ss.insert(rak[i]);
	//~ For(i,1,n) printf("%lld ",rak[i]);
	//~ puts("");
	For(i,1,q){
			printf("\n");
		int p=*ss.upper_bound(rak[be[i]]);
		if(ss.upper_bound(rak[be[i]])==ss.end()){
			printf("-1");
			continue;
		}
		while(1){
			if(rmq(sa[p],be[i])==len-sa[p]+1){
				if(ss.upper_bound(p)==ss.end()){
					printf("-1");
					break;
				}
				p=*ss.upper_bound(p);
				continue;
			}
			//~ cout<<sa[p]<<" "<<endl;
			For(j,sa[p],sa[p]+rmq(sa[p],be[i])){
				printf("%c",s[j]);
			}
			break;
		}
	}
#ifdef LOCAL
    Debug("\nMy Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}
/*
dabab
3
ab
abaa
bab

*/

2024/6/21 11:10
加载中...