poj 3581

十分易错的题,后缀数组与最小表示都可行,我用后缀数组做。

注意:

1. 必须可分成三段。

2. 后缀数组最后一个字符应定义成最大数。

3.求第二段与第三段的划分时,数组应扩成两倍,再求后缀数组。

易错例子:

8
5 0 3 1 2 3 1 4
错误程序输出:
0
5
1
3
4
1
3
2
正确的应该是:
0
5
1
3
2
1
3
4
代码:
#include<iostream>
#include<fstream>

using namespace std;
#define N 400010

int sa[N],sa1[N],rank[N],rank1[N],c[N],h[N];
int m[N];


int n,pow,count;

int cmp(const void *a,const void *b){
	int x=*(int*)a;
	int y=*(int*)b;
	if(rank[x]!=rank[y])
		return(1);
	else
		if(rank[x+pow]!=rank[y+pow])
			return(1);
		else
			return(0);
}

int cmp1(const void *a,const void *b){
	return m[*((int *)a)]-m[*((int *)b)];
}

void creat(){
	int i,j,k;
	
	for(i=0;i<n;i++)
		sa[i]=i;
	qsort(sa,n,sizeof(int),cmp1);
	

	for(i=0,j=0;i<n;i++)
	{
		if(i>0&&m[sa[i]]!=m[sa[i-1]])
			j++;
		rank[sa[i]]=j;
	}

	for(pow=1;pow<n;pow*=2)
	{
		for(i=0;i<n;i++)
			c[i]=0;
		for(i=0;i<n;i++)
			if(sa[i]+pow<n)
				c[rank[sa[i]+pow]]++;
			else
				c[rank[sa[i]]]++;
		for(i=1;i<n;i++)
			c[i]+=c[i-1];
		for(i=n-1;i>=0;i--)
			if(sa[i]+pow<n)
				sa1[--c[rank[sa[i]+pow]]]=sa[i];
			else
				sa1[--c[rank[sa[i]]]]=sa[i];
		for(i=0;i<n;i++)
			c[i]=0;
		for(i=0;i<n;i++)
			c[rank[sa1[i]]]++;
		for(i=1;i<n;i++)
			c[i]+=c[i-1];
		for(i=n-1;i>=0;i--)
			sa[--c[rank[sa1[i]]]]=sa1[i];
		for(i=0,j=0;i<n;i++)
		{
			if(i>0&&cmp(&sa[i],&sa[i-1])!=0)
				j++;
			rank1[sa[i]]=j;
		}
		for(i=0;i<n;i++)
			rank[i]=rank1[i];
	}
}



int a[200001];

int main(){
	int i,j,k,mid;
//	ifstream cin("in.txt");
	int n1,n2;
	int sm;
	//cin>>sm;
	scanf("%d",&sm);
	for(i=0;i<sm;i++)
		scanf("%d",&a[i]);
//		cin>>a[i];
	for(i=0;i<sm;i++)
		m[sm-i-1]=a[i];
	m[sm]=a[0]+10;
	n=sm+1;
	creat();
	
	for(i=0;;i++)
		if(sa[i]>=2)
			break;
	n1=sm-1-sa[i];
	n=0;
	for(j=sm-1;j>n1;j--)
		m[n++]=a[j];
	for(i=0;i<n;i++)
		m[n+i]=m[i];
	m[2*n]=a[0]+10;
	n=2*n+1;
	creat();
	for(i=0;;i++)
		if(sa[i]<n/2&&sa[i]>=1)
			break;
	n=n/2+1;
	n2=n-2-sa[i]+n1+1;
	for(i=n1;i>=0;i--)
		cout<<a[i]<<endl;
	for(i=n2;i>n1;i--)
		cout<<a[i]<<endl;
	for(i=sm-1;i>n2;i--)
		cout<<a[i]<<endl;
	return(0);
}


posted on 2011-03-15 15:20  宇宙吾心  阅读(311)  评论(0)    收藏  举报

导航