BZOJ 1031

把字符串複製一遍,用後綴數組排序,按順序輸出sa[i]<n的後綴中第n個字母即可。第一次後綴數組啊。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#define N 200010
using namespace std;
char s[N];
int r[N], sa[N], n;
namespace Get_Suffix
{
  int wa[N], wb[N], ws[N], wv[N];
  bool cmp(int *r,int a,int b,int l) { return r[a] == r[b] && r[a+l] == r[b+l]; }
  void da(int *r,int *sa,int n,int m) {
    int i, j, p, *x = wa, *y = wb, *t;
    for(i=0;i<m;i++) ws[i] = 0;
    for(i=0;i<n;i++) ws[x[i]=r[i]]++;
    for(i=1;i<m;i++) ws[i] += ws[i-1];
    for(i=n-1;i>=0;i--) sa[--ws[x[i]]] = i;
    for(j=1,p=1;p<n;j*=2,m=p) {
      for(p=0,i=n-j;i<n;i++) y[p++] = i;
      for(i=0;i<n;i++) if(sa[i]>=j) y[p++] = sa[i]-j;
      for(i=0;i<n;i++) wv[i] = x[y[i]];
      for(i=0;i<m;i++) ws[i] = 0;
      for(i=0;i<n;i++) ws[wv[i]]++;
      for(i=1;i<m;i++) ws[i] += ws[i-1];
      for(i=n-1;i>=0;i--) sa[--ws[wv[i]]] = y[i];
      for(t=x,x=y,y=t,x[sa[0]]=0,i=1,p=1;i<n;i++) 
	x[sa[i]] = cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
    }
    return;
  }
}

int main()
{
  scanf("%s",s);
  n = strlen(s);
  for(int i=0;i<n;i++) r[i+n] = r[i] = s[i];
  r[2*n] = 0;
  Get_Suffix::da(r,sa,2*n+1,128);
  for(int i=0;i<2*n+1;i++) 
    if(sa[i]<n) putchar(r[sa[i]+n-1]);
  putchar('\n');
  return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章