压缩后缀数组

来源:互联网 发布:去哪里下载ubuntu 编辑:程序博客网 时间:2024/05/22 13:36

Time Limit : 3000/1000ms(Java/Other)   Memory Limit : 65535/32768K (Java/Other)

Total Submission(s) :2   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

A newtechnology about suffix array called compressed suffix array is beingresearched.Let SA be the suffix array for string T. In the base case, we denoteSA by SA0, and let n0=n be the number of its entries. For simplicity inexposition, we assume that n is a power of 2. In the inductive phase k, westart with suffix array SAk, which is available by induction. It has nk=n/(2^k)entries and stores a permutation of {1,2,...,nk}. (Intuitively, thispermutation is that resulting from sorting the suffixes of T whose suffixpointers are multiple of 2^k.)
we run two main steps to transform SAk into an equivalent but more succinctrepresentation:
step 1. We define a function Fik, where Fik(i)=j if and only if SAk[i] is oddand SAk[j]=SAk[i]+1. In summary, for 1<=i<=nk, we have
Fik(i)=j, if SAk[i] mod 2 = 1 and SAk[j]=SAk[i]+1
Fik(i)=i, otherwise
step 2. Pack together the even values from SAk and divide each of them by 2.The resulting values form a permutation of {1,2,...,nk+1}, wherenk+1=nk/2=n/2^(k+1). Store them into a new suffix array SAk+1 entries, andremove the old suffix array SAk.
The following example illustrates the effect of a single application of Steps1-2.
SA0:
15 16 31 13 17 19 28 10 7 4 1 21 24 32 14 30 12 18 27 9 6 3 20 23 29 11 26 8 52 22 25
Fi0:
2 2 14 15 18 23 7 8 28 10 30 31 13 14 15 16 17 18 7 8 21 10 23 13 16 17 27 2821 30 31 27
SA1:
8 14 5 2 12 16 7 15 6 9 3 10 13 4 1 11
Fik can be stored in a particular way in O(n) bits, and SAk+1 occupy half spaceof SAk, So we can compress the suffix array by repeat steps 1-2. Now, the questionis, if we have known SAk+1 and Fik, how can we get the SAk?

Input

Youwill be given a number of cases in the input. Each case starts with a linecontaining n. The first line contains a positive integer n, which is a power of2, (2<=n<=2^14)
Followed by 2 lines.
The first line contains n integers represent for Fik.
The second line contains k integers (k=n/2) represent for SAk+1.
The input terminates with EOF.

Output

Foreach input data set output one line, contains the numbers of SAk (each numberare separated by a space).

Sample Input

32

2 2 1415 18 23 7 8 28 10 30 31 13 14 15 16 17 18 7 8 21 10 23 13 16 17 27 28 21 30 3127

8 14 52 12 16 7 15 6 9 3 10 13 4 1 11

Sample Output

15 1631 13 17 19 28 10 7 4 1

/*题目大意:fio[i]是SA0[i]得到,如果SA0[i]为奇数,将SA0[i]+1=SA0[j]中找到j;fi0[i]=j;如果SA0[i]为偶数,fi0[i]=i;将SA0中的偶数/2的值  依次存入SA1数组中:题目给出fi0,SA1;求SA0。if(fi0[i] == i)sa0[i] = sa1[++ cnt]*2; if(fi0[i] != i) sa0[i] = sa0[fi0[i]] - 1;*/  #include<iostream>#include<cstdio>#include<cstring>using namespace std;int fi0[60000],sa1[60000],sa0[60000];int main(){//    freopen("a.txt","r",stdin);    int n, i;    while(scanf("%d",&n)!=EOF)    {        for(i = 1; i <= n; ++ i)            scanf("%d",&fi0[i]);        for(i = 1; i <= n/2; ++ i)            scanf("%d",&sa1[i]);        memset(sa0,0,sizeof(sa0));        int cnt = 0;        for(i = 1; i <= n; ++ i)            if(fi0[i] == i)                sa0[i] = sa1[++ cnt]*2;        for(i = 1; i <= n; ++ i)            if(fi0[i] != i)               sa0[i] = sa0[fi0[i]] - 1;        for(i = 1; i < n; ++ i)            cout << sa0[i] << ' ';        cout << sa0[n] << endl;    }    return 0;}

21 24 32 14 30 12 18 27 9 6 3 20 23 29 11 26 8 5 2 2225

0 0
原创粉丝点击