題意:
給乙個長度為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 #include2view codeusing
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 }
字尾陣列 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,如...