Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

倍增算法后缀数组(454MS)

Posted by hahalidaxin at 2015-11-29 10:54:06 on Problem 3294
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std;

const int maxn = 200000+10;

int s[maxn];
int sa[maxn],c[maxn],t[maxn],t2[maxn];

void build_sa(int m,int n) {
	int i,*x=t,*y=t2;
	for(i=0;i<m;i++) c[i]=0;
	for(i=0;i<n;i++) c[x[i]=s[i]]++;
	for(i=1;i<m;i++) c[i]+=c[i-1];
	for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
	
	for(int k=1;k<=n;k<<=1) {
		int p=0;
		for(i=n-k;i<n;i++) y[p++]=i;
		for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
		
		for(i=0;i<m;i++) c[i]=0;
		for(i=0;i<n;i++) c[x[y[i]]]++;
		for(i=0;i<m;i++) c[i]+=c[i-1];
		for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
		
		swap(x,y);
		p=1; x[sa[0]]=0;
		for(i=1;i<n;i++) 
			x[sa[i]]=y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
		if(p>=n) break;
		m=p;
	}
}
int rank[maxn],height[maxn];
void getHeight(int n) {
	int i,j,k=0;
	for(i=0;i<=n;i++) rank[sa[i]]=i;
	for(i=0;i<n;i++) {
		if(k) k--;
		j=sa[rank[i]-1];
		while(s[j+k]==s[i+k]) k++;
		height[rank[i]]=k;
	}
}

int T;
char a[maxn];

int f[200],kase;
vector<int> st;
int can(int limit,int n,int len) {
	int cnt=1,ok=0;
	st.clear();
	f[sa[1]/len]=kase;
	for(int i=2;i<=n;i++) {
		if(height[i]<limit) {
			cnt=1;
			f[sa[i]/len]=++kase;   //检查每一个组中 
		}
		else {
			if(f[sa[i]/len]!=kase) {
				f[sa[i]/len]=kase;
				if(cnt>=0) cnt++;
				if(cnt>T/2) {
					ok=1;
					st.push_back(sa[i]);
					cnt=-1;
				}
			}
		}
	}
	return ok;
}
void init() {
	kase=1;
	memset(sa,0,sizeof(sa));
	memset(f,0,sizeof(f));
}
int main() {
	//freopen("in.in","r",stdin);
	//freopen("out.out","w",stdout);
	while(scanf("%d",&T)==1 && T) {
		init();
		int len,n=0;
		for(int i=0;i<T;i++) {
			scanf("%s",&a);
			len=strlen(a);
			for(int j=0;j<len;j++) s[n++]=a[j]+100;
			s[n++]=i+1;
		}
		n--;
		s[n]=0;
		
		build_sa(250,n+1);
		getHeight(n);
		
		int L=0,R=len+1;
		while(L<R) {
			int M=L+(R-L+1)/2;
			if(can(M,n,len+1)) L=M;
			else R=M-1;
		}
		can(L,n,len+1);
		if(L==0) printf("?\n");
		else {
			for(int i=0;i<st.size();i++)  {
				for(int j=st[i];(j-st[i]+1)<=L;j++)
					printf("%c",s[j]-100);
				putchar('\n');
			}
		}
		putchar('\n');
	}
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator