POJ3581 Sequence 字尾樹組

2022-05-23 18:18:08 字數 1595 閱讀 9121

題意:n個數字組成的序列,第乙個數字最大,,把序列分成3部分,每個部分分別翻轉,輸出翻轉後字典序最小的序列。。

字尾陣列變一下,,先求出 第乙個分割的位置,,然後再求一次字尾陣列,,求出第二個位置。。輸出就好了。

此題要採用單組輸入。。。

1 #include 

2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include

9 #include 10 #include 11 #include 12 #include 13 #include 14

using

namespace

std;

15 typedef unsigned long

long

ull;

16 typedef long

long

ll;17

const

int inf = 0x3f3f3f3f;18

const

double eps = 1e-8;19

const

int maxn = 2e5+10;20

int s[maxn], rev_s[maxn << 1

];21

intsa[maxn], rank[maxn], tmp[maxn];

22int

k, sort_len;

23bool cmp(int i, int

j)2433}

34void build_sa(int str, int

len)

3542

for (k = 1; k <= len; k *= 2)43

50for (int i = 0; i <= len; i++)

51 rank[i] =tmp[i];52}

53}54int main(void)55

74int len = n - pos1 - 1

;75 reverse_copy(s+pos1+1, s+n, rev_s);

76 reverse_copy(s+pos1+1, s+n, rev_s+len);

77 build_sa(rev_s, len << 1

);78

intpos2;

79for (int i = 0; i <= 2 * len; i++)

8085

for (int i = pos1; i >= 0; i--)

86 printf("

%d\n

",s[i]);

87for (int i = pos2+pos1+1; i > pos1; i--)

88 printf("

%d\n

",s[i]);

89for (int i = n-1; i > pos2+pos1+1; i--)

90 printf("

%d\n

", s[i]);91}

92return0;

93 }

POJ3581 Sequence 字尾陣列)

大致題意 給出n個數,把這個數列分為三段,再把三段反轉後連線在一起成為乙個新串,求字典序最小的新串。大致思路 由於需要翻轉,所以在輸入時就按照反序輸入。比如樣例輸入是5 10 1 2 3 4。我們從後向前讀入就變為5 4 3 2 1 10。對這列數求出字尾陣列。在大於2的後最中找到最小的字尾並輸出。...

POJ3581 Sequence(字尾陣列)

題意 給乙個串,串的第乙個字元比後面的都大,要把它分成三段,然後反轉每一段,求能得到的字典序最小的串是什麼。首先,第一段是可以確定的 把原串反轉,因為第乙個字元是最大的,它是唯一的,不存在反轉串的字尾之間有包含關係,所以取最小的字尾這就是第一段的字串 然後後面兩段,如果確定分割位置可以發現這兩段字串...

字尾陣列 poj3581 Sequence

考慮第一次切割,必然切割的是翻轉後字典序最小的字首,偽證 若切割位置更靠前 則會導致第乙個數翻轉後更靠前,字典序必然更大。若切割位置更靠後,則顯然也會導致字典序更大。sa即可 對於第二次切割,有結論 將序列分割成兩段再分別翻轉得到的序列,可以看作是將兩個原序列拼接得到的新序列中的某個字串翻轉得到的序...