Nhảy chuyển đến

Hậu tố số tổ tóm tắt

Một ít ước định

Tự phù xuyến tương quan định nghĩa thỉnh tham khảoTự phù xuyến cơ sở.

Tự phù xuyến hạ tiêu từBắt đầu.

Tự phù xuyếnChiều dài vì.

"Hậu tố"Đại chỉ lấy đệCái tự phù mở đầu hậu tố, tồn trữ khi dùngĐại biểu tự phù xuyếnHậu tố.

Hậu tố số tổ là cái gì?

Hậu tố số tổ ( Suffix Array ) chủ yếu quan hệ đến hai cái số tổ:Cùng.

Trong đó,Tỏ vẻ đem sở hữu hậu tố bài tự sau đệTiểu nhân hậu tố đánh số, cũng là theo như lời hậu tố số tổ, sau văn cũng xưng đánh số số tổ;

Tỏ vẻ hậu tốXếp hạng, là quan trọng phụ trợ số tổ, sau văn cũng xưng xếp hạng số tổ.

Này hai cái số tổ thỏa mãn tính chất:.

Giải thích

Hậu tố số tổ thí dụ mẫu:

Hậu tố số tổ như thế nào cầu?

O(n^2logn) cách làm

Tin tưởng cái này cách làm đại gia vẫn là có thể chính mình nghĩ đến: Đem thịnh có toàn bộ hậu tố tự phù xuyến số tổ tiến hànhsortBài tự, bởi vì bài tự tiến hànhThứ tự phù xuyến tương đối, mỗi lần tự phù xuyến tương đối muốnThứ tự phù tương đối, cho nên cái này bài tự làThời gian phức tạp độ.

O(nlog^2n) cách làm

Cái này cách làm phải dùng đến tăng gấp bội tư tưởng.

Đầu tiên đối tự phù xuyếnSở hữu chiều dài vìTử xuyến, tức mỗi cái tự phù tiến hành bài tự, được đến bài tự sau đánh số số tổCùng xếp hạng số tổ.

Tăng gấp bội quá trình:

  1. Dùng hai cái chiều dài vìTử xuyến xếp hạng, tứcCùng,Làm bài tự đệ nhất cửa thứ hai kiện tự, liền có thể đối tự phù xuyếnMỗi cái chiều dài vìTử xuyến:Tiến hành bài tự, được đếnCùng;

  2. Lúc sau dùng hai cái chiều dài vìTử xuyến xếp hạng, tứcCùng,Làm bài tự đệ nhất cửa thứ hai kiện tự, liền có thể đối tự phù xuyếnMỗi cái chiều dài vìTử xuyến:Tiến hành bài tự, được đếnCùng;

  3. Lấy này tăng gấp bội, dùng chiều dài vìTử xuyến xếp hạng, tứcCùng,Làm bài tự đệ nhất cửa thứ hai kiện tự, liền có thể đối tự phù xuyếnMỗi cái chiều dài vìTử xuyếnTiến hành bài tự, được đếnCùng.Trong đó, cùng loại chữ cái tự bài tự quy tắc, đươngKhi,Coi là vô cùng tiểu;

  4. Tức là tử xuyếnXếp hạng, như vậy đươngKhi, được đến đánh số số tổ,Cũng chính là chúng ta yêu cầu hậu tố số tổ.

Quá trình

Tăng gấp bội bài tự sơ đồ:

Hiển nhiên tăng gấp bội quá trình là,Mà mỗi lần tăng gấp bội dùngsortĐối tử xuyến tiến hành bài tự là,Mà mỗi lần tử xuyến tương đối tiêu phíThứ tự phù tương đối;

Trừ cái này ra, mỗi lần tăng gấp bội ởsortBài tự xong sau, còn có thêm vàoThời gian phức tạp độ, đổi mớiThao tác, nhưng là tương đối vớiBị xem nhẹ bất kể;

Cho nên cái này thuật toán thời gian phức tạp độ chính là.

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include&LTalgorithm>
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>

usingnamespacestd;

constintN=1000010;

chars[N];
intn,w,sa[N],rk[N1],oldrk[N1];

// vì phòng ngừa phỏng vấn rk[i+w] dẫn tới số tổ vượt rào, khai gấp hai số tổ.
// đương nhiên cũng có thể ở phỏng vấn trước phán đoán hay không vượt rào, nhưng trực tiếp khai gấp hai số tổ phương tiện một ít.

intmain(){
inti,p;

scanf("%s",s+1);
n=strlen(s+1);
for(i=1;in;++i)sa[i]=i,rk[i]=s[i];

for(w=1;wn;w1){
sort(sa+1,sa+n+1,[](intx,inty){
returnrk[x]==rk[y]?rk[x+w]rk[y+w]:rk[x]rk[y];
});// nơi này dùng tới rồi lambda
memcpy(oldrk,rk,sizeof(rk));
// bởi vì tính toán rk thời điểm nguyên lai rk sẽ bị bao trùm, muốn trước phục chế một phần
for(p=0,i=1;in;++i){
if(oldrk[sa[i]]==oldrk[sa[i-1]]&&
oldrk[sa[i]+w]==oldrk[sa[i-1]+w]){
rk[sa[i]]=p;
}else{
rk[sa[i]]=++p;
}// nếu hai cái tử xuyến tương đồng, chúng nó đối ứng rk cũng yêu cầu tương đồng, cho nên muốn đi trọng
}
}

for(i=1;in;++i)printf("%d",sa[i]);

return0;
}

O(nlogn) cách làm

Ở vừa mớiCách làm trung, đơn thứ bài tự là,Nếu có thểBài tự, là có thểTính toán hậu tố số tổ.

Trước trí tri thức:Đếm hết bài tự,Số đếm bài tự.

Bởi vì tính toán hậu tố số tổ trong quá trình bài tự mấu chốt tự là xếp hạng, giá trị vực vì,Hơn nữa là một cái hai ý nghĩa kiện tự bài tự, có thể sử dụng số đếm bài tự ưu hoá đến.

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include&LTalgorithm>
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>

usingnamespacestd;

constintN=1000010;

chars[N];
intn,sa[N],rk[N1],oldrk[N1],id[N],cnt[N];

intmain(){
inti,m,p,w;

scanf("%s",s+1);
n=strlen(s+1);
m=127;
for(i=1;in;++i)++cnt[rk[i]=s[i]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;
memcpy(oldrk+1,rk+1,n*sizeof(int));
for(p=0,i=1;in;++i){
if(oldrk[sa[i]]==oldrk[sa[i-1]]){
rk[sa[i]]=p;
}else{
rk[sa[i]]=++p;
}
}

for(w=1;wn;w1,m=n){
// đối cửa thứ hai kiện tự: id[i] + w tiến hành đếm hết bài tự
memset(cnt,0,sizeof(cnt));
memcpy(id+1,sa+1,
n*sizeof(int));// id bảo tồn một phần nhi sa copy, thực chất thượng liền tương đương với oldsa
for(i=1;in;++i)++cnt[rk[id[i]+w]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[id[i]+w]]--]=id[i];

// đối cửa thứ nhất kiện tự: id[i] tiến hành đếm hết bài tự
memset(cnt,0,sizeof(cnt));
memcpy(id+1,sa+1,n*sizeof(int));
for(i=1;in;++i)++cnt[rk[id[i]]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[id[i]]]--]=id[i];

memcpy(oldrk+1,rk+1,n*sizeof(int));
for(p=0,i=1;in;++i){
if(oldrk[sa[i]]==oldrk[sa[i-1]]&&
oldrk[sa[i]+w]==oldrk[sa[i-1]+w]){
rk[sa[i]]=p;
}else{
rk[sa[i]]=++p;
}
}
}

for(i=1;in;++i)printf("%d",sa[i]);

return0;
}

Một ít hằng số ưu hoá

Nếu ngươi đem mặt trên kia phân số hiệu giao choLOJ #111: Hậu tố bài tựThượng:

Đây là bởi vì, mặt trên kia phân số hiệu hằng số đích xác rất lớn.

Cửa thứ hai kiện tự không cần đếm hết bài tự

Tự hỏi một chút cửa thứ hai kiện tự bài tự thực chất, kỳ thật chính là đem vượt qua tự phù xuyến phạm vi ( tức)Phóng tớiSố tổ phần đầu, sau đó đem dư lại y nguyên trình tự để vào:

1
2
3
4
intcur=0;
for(inti=n-w+1;in;i++)id[++cur]=i;
for(inti=1;in;i++)
if(sa[i]>w)id[++cur]=sa[i]-w;

Ưu hoá đếm hết bài tự giá trị vực

Mỗi lần đốiTiến hành đổi mới lúc sau, chúng ta đều tính toán một cái,Cái nàyTức làGiá trị vực, đem giá trị vực đổi thành nó là được.

Nếu xếp hạng đều không giống nhau nhưng trực tiếp sinh thành hậu tố số tổ

Suy xét tânSố tổ, nếu này giá trị vực vìNhư vậy mỗi cái xếp hạng đều bất đồng, lúc này không cần lại bài tự.

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include&LTalgorithm>
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>

usingnamespacestd;

constintN=1000010;

chars[N];
intn;
intm,p,rk[N*2],oldrk[N],sa[N*2],id[N],cnt[N];

intmain(){
scanf("%s",s+1);
n=strlen(s+1);
m=128;

for(inti=1;in;i++)cnt[rk[i]=s[i]]++;
for(inti=1;im;i++)cnt[i]+=cnt[i-1];
for(inti=n;i>=1;i--)sa[cnt[rk[i]]--]=i;

for(intw=1;;w1,m=p){// m = p tức vì giá trị vực ưu hoá
intcur=0;
for(inti=n-w+1;in;i++)id[++cur]=i;
for(inti=1;in;i++)
if(sa[i]>w)id[++cur]=sa[i]-w;

memset(cnt,0,sizeof(cnt));
for(inti=1;in;i++)cnt[rk[i]]++;
for(inti=1;im;i++)cnt[i]+=cnt[i-1];
for(inti=n;i>=1;i--)sa[cnt[rk[id[i]]]--]=id[i];

p=0;
memcpy(oldrk,rk,sizeof(oldrk));
for(inti=1;in;i++){
if(oldrk[sa[i]]==oldrk[sa[i-1]]&&
oldrk[sa[i]+w]==oldrk[sa[i-1]+w])
rk[sa[i]]=p;
else
rk[sa[i]]=++p;
}

if(p==n)break;// p = n khi không cần lại bài tự
}

for(inti=1;in;i++)printf("%d",sa[i]);

return0;
}

O(n) cách làm

Ở giống nhau đề mục trung, hằng số nhỏ lại tăng gấp bội cầu hậu tố số tổ là hoàn toàn đủ dùng, cầu hậu tố số tổ bên ngoài bộ phận cũng thường xuyên cóPhức tạp độ, tăng gấp bội cầu giải hậu tố số tổ sẽ không trở thành bình cảnh.

Nhưng nếu gặp được đặc thù đề mục, thời hạn so khẩn đề mục, hoặc là ngươi muốn theo đuổi càng đoản dùng khi, liền yêu cầu học tậpCầu hậu tố số tổ phương pháp.

SA-IS

Có thể tham khảoHướng dẫn bài tự cùng SA-IS thuật toán,Mặt khác nóBình luận giao diệnCũng có tham khảo giá trị.

DC3

Có thể tham khảo[2009] hậu tố số tổ —— xử lý tự phù xuyến hữu lực công cụ by. La tuệ khiên.

Hậu tố số tổ ứng dụng

Tìm kiếm nhỏ nhất tuần hoàn di động vị trí

Đem tự phù xuyếnPhục chế một phần biến thànhLiền chuyển hóa thành hậu tố bài tự vấn đề.

Ví dụ mẫu:“JSOI2007” tự phù mã hóa.

Ở tự phù xuyến trung tìm tử xuyến

Nhiệm vụ là tại tuyến mà ở chủ xuyếnTrung tìm kiếm hình thức xuyến.Tại tuyến ý tứ là, chúng ta đã trước biết biết chủ xuyến,Nhưng là đương thả chỉ đương dò hỏi khi mới biết được hình thức xuyến.Chúng ta có thể trước cấu tạo raHậu tố số tổ, sau đó tra tìm tử xuyến.Nếu tử xuyếnTrung xuất hiện, nó nhất định làMột ít hậu tố tiền tố. Bởi vì chúng ta đã đem sở hữu hậu tố bài tự, chúng ta có thể thông qua ởSố tổ trung nhị phânTới thực hiện. Tương đối tử xuyếnCùng trước mặt hậu tố thời gian phức tạp độ vì,Bởi vậy tìm tử xuyến thời gian phức tạp độ vì.Chú ý, nếu nên tử xuyến ởTrung xuất hiện nhiều lần, mỗi lần xuất hiện đều là ởSố tổ trung liền nhau. Bởi vậy xuất hiện số lần có thể thông qua lại lần nữa nhị phân tìm được, phát ra mỗi lần xuất hiện vị trí cũng thực nhẹ nhàng.

Từ tự phù xuyến đầu đuôi lấy tự phù nhỏ nhất hóa từ điển tự

Ví dụ mẫu:“USACO07DEC” Best Cow Line.

Đề ý: Cho ngươi một chữ phù xuyến, mỗi lần từ đầu hoặc đuôi lấy một chữ phù tạo thành tự phù xuyến, hỏi sở hữu có thể tạo thành tự phù xuyến trung từ điển tự nhỏ nhất một cái.

Lời giải trong đề bài

Bạo lực cách làm chính là mỗi lần nhất hưMà phán đoán trước mặt hẳn là lấy đầu vẫn là đuôi ( tức tương đối lấy đầu được đến tự phù xuyến cùng lấy đuôi được đến thế vai lớn nhỏ ), chỉ cần ưu hoá này một phán đoán quá trình là được.

Bởi vì yêu cầu ở nguyên xuyến hậu tố cùng thế vai hậu tố cấu thành tập hợp nội khá lớn tiểu, có thể đem thế vai ghép nối ở nguyên xuyến sau, cũng ở bên trong hơn nữa một cái không xuất hiện quá tự phù ( như#,Số hiệu trung có thể trực tiếp sử dụng không tự phù ), cầu hậu tố số tổ, có thểHoàn thành này một phán đoán.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include&LTcctype>
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>

usingnamespacestd;

constintN=1000010;

chars[N];
intn,sa[N],id[N],oldrk[N*2],rk[N*2],px[N],cnt[N];

boolcmp(intx,inty,intw){
returnoldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w];
}

intmain(){
inti,w,m=200,p,l=1,r,tot=0;

cin>>n;
r=n;

for(i=1;in;++i)
while(!is Alpha(s[i]=getchar()));
for(i=1;in;++i)
rk[i]=rk[2*n+2-i]=s[i];// ghép nối chính phản hai chữ phù xuyến, trung gian không ra một chữ phù

n=2*n+1;
// cầu hậu tố số tổ
for(i=1;in;++i)++cnt[rk[i]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;

for(w=1;wn;w*=2,m=p){// m=p chính là ưu hoá đếm hết bài tự giá trị vực
for(p=0,i=n;i>n-w;--i)id[++p]=i;
for(i=1;in;++i)
if(sa[i]>w)id[++p]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(i=1;in;++i)++cnt[px[i]=rk[id[i]]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[px[i]]--]=id[i];
memcpy(oldrk,rk,sizeof(rk));
for(p=0,i=1;in;++i)
rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
}
// lợi dụng hậu tố số tổ O(1) tiến hành phán đoán
while(lr){
printf("%c",rk[l]rk[n+1-r]?s[l++]:s[r--]);
if((++tot)%80==0)puts("");// hồi xe
}

return0;
}

height số tổ

LCP ( dài nhất công cộng tiền tố )

Hai chữ phù xuyếnCùngLCP chính là lớn nhất() khiến cho.

Bên dưới trung lấyTỏ vẻ hậu tốCùng hậu tốDài nhất công cộng tiền tố ( chiều dài ).

height số tổ định nghĩa

,Tức đệDanh hậu tố cùng nó trước một người hậu tố dài nhất công cộng tiền tố.

Có thể coi làm.

O(n) cầu height số tổ yêu cầu một cái dẫn lý

Chứng minh

ĐươngKhi, thượng thức hiển nhiên thành lập ( bên phải nhỏ hơn hoặc bằng).

ĐươngKhi:

Căn cứĐịnh nghĩa, có.

Nếu hậu tốCùng hậu tốCó chiều dài vìDài nhất công cộng tiền tố,

Như vậy không ngại dùngTới tỏ vẻ cái này dài nhất công cộng tiền tố. ( trong đóLà một chữ phù,Là chiều dài vìTự phù xuyến, phi không )

Như vậy hậu tốCó thể tỏ vẻ vì,Hậu tốCó thể tỏ vẻ vì.(,Khả năng vì không xuyến,Phi không )

Tiến thêm một bước mà, hậu tốCó thể tỏ vẻ vì,Tồn tại hậu tố ().

Bởi vì hậu tốỞ lớn nhỏ quan hệ xếp hạng thượng chỉ so hậu tốCũng chính là hậu tố,Tiểu một vị, mà.

Cho nênHậu tố,Hiển nhiên hậu tốCùng hậu tốCó công cộng tiền tố.

Vì thế liền có thể đến raÍt nhất là,Cũng tức.

O(n) cầu height số tổ số hiệu thực hiện

Lợi dụng mặt trên cái này dẫn lý bạo lực cầu có thể:

1
2
3
4
5
6
for(i=1,k=0;in;++i){
if(rk[i]==0)continue;
if(k)--k;
while(s[i+k]==s[sa[rk[i]-1]+k])++k;
height[rk[i]]=k;
}

Sẽ không vượt qua,Nhiều nhất giảmThứ, cho nên nhiều nhất thêmThứ, tổng phức tạp độ chính là.

height số tổ ứng dụng

Hai tử xuyến dài nhất công cộng tiền tố

Cảm tính lý giải: NếuVẫn luôn lớn hơn nào đó số, trước nhiều như vậy vị liền vẫn luôn không thay đổi quá; ngược lại, bởi vì hậu tố đã lập tự, không có khả năng thay đổi lúc sau biến trở về tới.

Nghiêm khắc chứng minh có thể tham khảo[2004] hậu tố số tổ by. Từ trí lỗi.

Có cái này định lý, cầu hai tử xuyến dài nhất công cộng tiền tố liền chuyển hóa vìRMQ vấn đề.

Tương đối một chữ phù xuyến hai cái tử xuyến lớn nhỏ quan hệ

Giả thiết yêu cầu tương đối chính làCùngLớn nhỏ quan hệ.

Nếu,.

Nếu không,.

Bất đồng tử xuyến số lượng

Tử xuyến chính là hậu tố tiền tố, cho nên có thể cái cử mỗi cái hậu tố, tính toán tiền tố tổng số, lại trừ lặp lại.

“Tiền tố tổng số” kỳ thật chính là tử xuyến cái số, vì.

Nếu ấn hậu tố bài tự trình tự cái cử hậu tố, mỗi lần tân tăng tử xuyến chính là trừ bỏ cùng thượng một cái hậu tố LCP dư lại tiền tố. Này đó tiền tố nhất định là tân tăng, nếu không sẽ phá hưTính chất. Chỉ có này đó tiền tố là tân tăng, bởi vì LCP bộ phận ở cái cử thượng một cái tiền tố khi tính toán qua.

Cho nên đáp án vì:

Xuất hiện ít nhất k thứ tử xuyến lớn nhất chiều dài

Ví dụ mẫu:“USACO06DEC” Milk Patterns.

Lời giải trong đề bài

Xuất hiện ít nhấtThứ ý nghĩa hậu tố bài tự sau có ít nhất liên tụcCái hậu tố lấy cái này tử xuyến làm công cộng tiền tố.

Cho nên, cầu ra mỗi liền nhauCáiNhỏ nhất giá trị, lại cầu này đó nhỏ nhất giá trị cực đại chính là đáp án.

Có thể sử dụng đơn điệu đội ngũGiải quyết, nhưng sử dụng cái khác phương thức cũng đủ để AC.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>
#include&LTset>

usingnamespacestd;

constintN=40010;

intn,k,a[N],sa[N],rk[N],oldrk[N],id[N],px[N],cnt[1000010],ht[N],ans;
multisetint>t;// multiset là tốt nhất viết thực hiện phương thức

boolcmp(intx,inty,intw){
returnoldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w];
}

intmain(){
inti,j,w,p,m=1000000;

scanf("%d%d",&n,&k);
--k;

for(i=1;in;++i)scanf("%d",a+i);// cầu hậu tố số tổ
for(i=1;in;++i)++cnt[rk[i]=a[i]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;

for(w=1;wn;w1,m=p){
for(p=0,i=n;i>n-w;--i)id[++p]=i;
for(i=1;in;++i)
if(sa[i]>w)id[++p]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(i=1;in;++i)++cnt[px[i]=rk[id[i]]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[px[i]]--]=id[i];
memcpy(oldrk,rk,sizeof(rk));
for(p=0,i=1;in;++i)
rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
}

for(i=1,j=0;in;++i){// cầu height
if(j)--j;
while(a[i+j]==a[sa[rk[i]-1]+j])++j;
ht[rk[i]]=j;
}

for(i=1;in;++i){// cầu sở hữu nhỏ nhất giá trị cực đại
t.insert(ht[i]);
if(i>k)t.erase(t.find(ht[i-k]));
ans=max(ans,*t.begin());
}

coutans;

return0;
}

Hay không có mỗ tự phù xuyến ở văn bản xuyến trung ít nhất không trùng điệp mà xuất hiện hai lần

Có thể nhị phân mục tiêu xuyến chiều dài,ĐemSố tổ phân chia thành bao nhiêu cái liên tục LCP lớn hơn hoặc bằngĐoạn, lợi dụng RMQ đối mỗi cái đoạn cầu trong đó xuất hiện số trung lớn nhất cùng nhỏ nhất hạ tiêu, nếu này hai cái hạ bia khoảng cách thỏa mãn điều kiện, tắc nhất định có chiều dài vìTự phù xuyến không trùng điệp mà xuất hiện hai lần.

Liên tục bao nhiêu cái tương đồng tử xuyến

Chúng ta có thể cái cử liên tục xuyến chiều dài,Dựa theoĐối toàn bộ xuyến tiến hành phân khối, đối liền nhau hai khối khối đầu tiến hành LCP cùng LCS tuần tra, cụ thể có thể thấy được[2009] hậu tố số tổ —— xử lý tự phù xuyến hữu lực công cụ.

Ví dụ mẫu:“NOI2016” ưu tú tách ra.

Kết hợp cũng tra tập

Nào đó đề mục cầu giải khi yêu cầu ngươi đem hậu tố số tổ phân chia thành bao nhiêu cái liên tục LCP chiều dài lớn hơn hoặc bằng mỗ một giá trị đoạn, đó là đemSố tổ phân chia thành bao nhiêu cái liên tục nhỏ nhất giá trị lớn hơn hoặc bằng mỗ một giá trị đoạn cũng thống kê mỗi một đoạn đáp án. Nếu có bao nhiêu thứ dò hỏi, chúng ta có thể đem dò hỏi ly tuyến. Quan sát đến đương cấp định giá trị đơn điệu giảm dần thời điểm, thỏa mãn điều kiện khu gian cái số luôn là càng ngày càng ít, mà khu mới gian đều là hai cái hoặc nhiều nguyên khu gian tương liên đoạt được, thả khu mới gian trung không bao hàm ở nguyên khu gian nội bộ phậnGiá trị đều vì giảm bớt đến cái này giá trị. Chúng ta chỉ cần giữ gìn một cái cũng tra tập, mỗi lần xác nhập liền nhau hai cái khu gian, cũng giữ gìn thống kê tin tức là được.

Kinh điển đề mục:“NOI2015” phẩm rượu đại hội

Kết hợp đoạn thẳng thụ

Nào đó đề mục làm ngươi cầu thỏa mãn điều kiện trước bao nhiêu cái số, mà này đó số lại ở phía sau chuế bài tự trung một cái khu gian nội. Lúc này chúng ta có thể dùng gộp vào bài tự tính chất tới xác nhập hai cái giao điểm tin tức, lợi dụng đoạn thẳng thụ giữ gìn cùng tuần tra khu gian đáp án.

Kết hợp đơn điệu sạn

Ví dụ mẫu:“AHOI2013” sai biệt

Lời giải trong đề bài

Số bị cộng trước hai hạng thực hảo xử lí, vì( mỗi cái hậu tố đều xuất hiệnThứ, hậu tố tổng trưởng là), mấu chốt là cuối cùng hạng nhất, tức hậu tố hai hai LCP.

Chúng ta biếtĐồng giá với.Cho nên, có thể đemNhớ làmĐối đáp án cống hiến.

Suy xét mỗi cái vị trí đối đáp án cống hiến là này đó hậu tố LCP, kỳ thật chính là từ nó bắt đầu hướng tả bao nhiêu cái liên tụcLớn hơn nó hậu tố trúng tuyển một cái, lại từ hướng hữu bao nhiêu cái liên tụcKhông nhỏ với nó hậu tố trúng tuyển một cái. Thứ này có thể dùngĐơn điệu sạnTính toán.

Đơn điệu sạn bộ phận cùng loại vớiLuogu P2659 mỹ lệ danh sáchCùng vớiHuyền tuyến pháp.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include&LTcstdio>
#include&LTcstring>
#include&LTiostream>

usingnamespacestd;

constintN=500010;

chars[N];
intn,sa[N],rk[N1],oldrk[N1],id[N],px[N],cnt[N],ht[N],sta[N],
top,l[N];
longlongans;

boolcmp(intx,inty,intw){
returnoldrk[x]==oldrk[y]&&oldrk[x+w]==oldrk[y+w];
}

intmain(){
inti,k,w,p,m=300;

scanf("%s",s+1);
n=strlen(s+1);
ans=1ll*n*(n-1)*(n+1)/2;
// cầu hậu tố số tổ
for(i=1;in;++i)++cnt[rk[i]=s[i]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;

for(w=1;wn;w1,m=p){
for(p=0,i=n;i>n-w;--i)id[++p]=i;
for(i=1;in;++i)
if(sa[i]>w)id[++p]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(i=1;in;++i)++cnt[px[i]=rk[id[i]]];
for(i=1;im;++i)cnt[i]+=cnt[i-1];
for(i=n;i>=1;--i)sa[cnt[px[i]]--]=id[i];
memcpy(oldrk,rk,sizeof(rk));
for(p=0,i=1;in;++i)
rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
}
// cầu height
for(i=1,k=0;in;++i){
if(k)--k;
while(s[i+k]==s[sa[rk[i]-1]+k])++k;
ht[rk[i]]=k;
}
// giữ gìn đơn điệu sạn
for(i=1;in;++i){
while(ht[sta[top]]>ht[i])--top;// top cùng loại với một cái kim đồng hồ
l[i]=i-sta[top];
sta[++top]=i;
}
// cuối cùng lợi dụng đơn điệu sạn tính ans
sta[++top]=n+1;
ht[n+1]=-1;
for(i=n;i>=1;--i){
while(ht[sta[top]]>=ht[i])--top;
ans-=2ll*ht[i]*l[i]*(sta[top]-i);
sta[++top]=i;
}

coutans;

return0;
}

Cùng loại đề mục:“HAOI2016” tìm tương đồng tự phù.

Bài tập

Tham khảo tư liệu

Bổn giao diện trung (4070a9bDẫn vào bộ phận ) chủ yếu dịch tự bác vănСуффиксный массивCùng với tiếng Anh phiên dịch bảnSuffix Array.Trong đó tiếng Nga bản bản quyền hiệp nghị vì Public Domain + Leave a Link; tiếng Anh bản bản quyền hiệp nghị vì CC-BY-SA 4.0.

Luận văn:

  1. [2004] hậu tố số tổ by. Hứa trí lỗi

  2. [2009] hậu tố số tổ —— xử lý tự phù xuyến hữu lực công cụ by. La tuệ khiên