hdu6223 字尾陣列

2022-01-29 08:21:21 字數 1195 閱讀 2390

題意:

給乙個長度為n的字串s[0..n-1],但i的後繼不再是i+1,而是(i*i+1)%n,求所有長度為n的「子串」中,字典序最大的是誰

n<=150000

分析:

如果是一般的字串,那麼直接求出字尾陣列就行,但現在後繼關係發生了變化

我們在倍增求字尾陣列的過程中,只關心某個位置的下個2^k的後繼,於是可以先倍增預處理出每個位置的nx[i][j]表示位置i的下個2^j的後繼是誰

時間複雜度o(nlogn)

1 #include2

using

namespace

std;

3const

int maxn=2e5;

4char s[maxn+50];5

int sa[maxn+50],rk[maxn+50];6

int t[maxn+50],t2[maxn+50],c[maxn+50];7

int nx[maxn+5][19];8

intlen,k;

9 queue q[maxn+5

];10

void getsa(int m)//

m表示最大字元的編碼

1133

34for(int i=0;i0;35

for(int i=0;i;

36for(int i=0;i1

];37

for(int i=len-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];

38swap(x,y);

39 p=1,x[sa[0]]=0;40

for(int i=1;ii)

41if(y[sa[i-1]]==y[sa[i]]&&y[nx[sa[i-1]][j]]==y[nx[sa[i]][j]]) x[sa[i]]=p-1;else x[sa[i]]=p++;

42if(p>=len) break

;43 m=p;44}

45}46int

main()

4763

64//

for(int i=0;i65

//for(int i=0;i66

//for(int i=0;i67

return0;

6869 }

view code

字尾陣列 HDU 4436

做法 首先應用求不同子串的演算法,自然想到字尾陣列,然後就是要統計以非 0 開始的字尾。考慮字尾 akak 1ak 2.an tmp 0 ak 0 tmp i tmp i 1 10 ai 0 sum i sum i 1 tmp i 那麼 以 am開始的字首和就是 sum n sum m 1 tmp ...

hdu 3518 字尾陣列

晚飯前寫的 一直wa,一直想不通,後來寫程式對拍了,一百組資料中錯了一組,然後還是想不通為什麼的,然後的然後看了別人的 然後瞬間知道自己為什麼wa!還是對字尾陣列了解的不夠,自己預設的是sa中排在前面的然後在字串陣列中下標也是在前面的,然後就沒有挨個比較相同長度中的取最大值和最小值,所以wa的可憐啊...

hdu 3518 字尾陣列

字尾陣列的題目主要是對三個陣列的利用 sa 記錄的是排名為i的字尾的首字母的下標 1 n rank 記錄的是首字母下標為i的字尾的排名 n height 記錄是j和j 1排序的最長公共字首 這道題求取的是不重疊的最少出現兩次的子串的個數 根據height j 陣列的性質,列舉長度然後按順序遍歷i,如...