求助SA桶排序
查看原帖
求助SA桶排序
199459
Masna_Kimoyo楼主2022/3/12 21:57

被桶排hack了,结果重新写从TLE变成了WA,求助

#include<bits/stdc++.h>
#define printlf(x) print(x),putchar('\n')
#define printsp(x) print(x),putchar(' ')
using namespace std;
const int N=1e6+5;
int rk[N],sa[N],oldrk[N],ans[N],num[N],id[N],px[N];
int n,cnt,w;
inline int read(){
    int x=0;
    bool w=0;
    char c=getchar();
    while(!isdigit(c))  w|=c=='-',c=getchar();
    while(isdigit(c))   x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return w?-x:x;
}
inline void print(int x){
    if(x<0) x=-x,putchar('-');
    if(x>9) print(x/10);
    putchar('0'+x%10);
}
string s="?";
inline bool cmp(const int &x,const int &y){
	return rk[x]==rk[y]?rk[x+w]<rk[y+w]:rk[x]<rk[y];
}
inline void Sort(){
	memset(num,0,sizeof(num));
	for(register int i=1;i<=n;++i)	++num[rk[i]=s[i]];
	for(register int i=1;i<=128;++i)	num[i]+=num[i-1];
	for(register int i=n;i;--i)	sa[num[rk[i]]--]=i;
}
inline void Get_sa(){
	Sort();
	int m=128;
	for(w=1;w<n;w<<=1){
		int p=0;
		for(register int i=n;i>n-w;--i)	id[++p]=i;
		for(register int i=1;i<=n;++i)	if(sa[i]>w)	id[++p]=sa[i]-w;
		memset(num,0,sizeof(num));
		for(register int i=1;i<=n;++i)	++num[px[i]=rk[id[i]]];
		for(register int i=1;i<=m;++i)	num[i]+=num[i-1];
		for(register int i=n;i;--i)	sa[num[px[i]]--]=id[i];
		memcpy(oldrk,rk,sizeof(rk));
		p=0;
		for(register int i=1;i<=n;++i)
			if(oldrk[sa[i]]==oldrk[sa[i-1]] && oldrk[sa[i]+w]==oldrk[sa[i-1]+w])	rk[sa[i]]=p;
			else	rk[sa[i]]=++p;
	}
}
signed main(){
//	freopen("P2870_2.in","r",stdin);
	n=read();
	string a;
	for(register int i=1;i<=n;++i){
		char ch;cin>>ch;a+=ch;
	}
	string b=a;reverse(b.begin(),b.end());s+=a+b; 
	n<<=1;
//	cout<<"OK\n";
	Get_sa();
	int l=1,r=n/2;
	while(l<r){
		if(s[l]<s[r])	ans[++cnt]=l++;
		else	if(s[l]>s[r])	ans[++cnt]=r--;
		else{
			if(rk[l]<rk[n-r+1])	ans[++cnt]=l++;
			else	ans[++cnt]=r--;
		}
	}
	ans[++cnt]=l;
//	cout<<s<<endl;
//	for(register int i=1;i<=n;++i)	cout<<sa[i]<<' ';cout<<endl;
//	for(register int i=1;i<=n;++i)	cout<<rk[i]<<' ';cout<<endl;
	for(register int i=1;i<=n/2;++i)
		if(i%80==0)	cout<<s[ans[i]]<<endl;
		else	cout<<s[ans[i]];
    return 0;	
}
2022/3/12 21:57
加载中...