后缀数组

21 篇文章 0 订阅
2 篇文章 0 订阅

后缀数组,,觉得没什么好讲的

可见黑书辣,白书辣什么的

觉得讲的很清楚啊

唯一一个需要理解的就是它计数排序的时候

var s:array[1..200000] of char;
	sum1:array['a'..'z'] of longint;
	height,sum:array[1..200000] of longint;
	rank,trank,sa,tsa:Array[1..400000] of longint;
	p,i,j,n,k:longint;
	ch:char;
procedure init;
begin
	while not(eoln) do
	begin
		inc(n);
		read(s[n]);
	end;
end;
procedure sorting(j:longint);
begin
	for i:=1 to n do sum[i]:=0;
	for i:=1 to n do inc(sum[rank[i+j]]);
	for i:=1 to n do inc(sum[i],sum[i-1]);
	for i:=n downto 1 do
	begin
		tsa[sum[rank[i+j]]]:=i;
		dec(sum[rank[i+j]]);
	end;
	for i:=1 to n do sum[i]:=0;
	for i:=1 to n do inc(sum[rank[i]]);
	for i:=1 to n do inc(sum[i],sum[i-1]);
	for i:=n downto 1 do
	begin
		sa[sum[rank[tsa[i]]]]:=tsa[i];
		dec(sum[rank[tsa[i]]]);
	end;
end;
procedure main;
begin
	init;
	for i:=1 to n do inc(sum1[s[i]]);
	for ch:='b' to 'z' do inc(Sum1[ch],sum1[chr(ord(ch)-1)]);
	for i:=n downto 1 do
	begin
		sa[sum1[s[i]]]:=i;
		dec(sum1[s[i]]);
	end;
	rank[sa[1]]:=1;
	p:=1;
	for i:=2 to n do
	begin
		if s[sa[i]]<>s[sa[i-1]] then inc(p);
		rank[sa[i]]:=p;
	end;
	j:=1;
	while (j<=n) do
	begin
		sorting(j);
		p:=1;
		trank[sa[1]]:=1;
		for i:=2 to n do
		begin
			if (rank[sa[i]]<>rank[sa[i-1]]) or  (rank[sa[i]+j]<>rank[sa[i-1]+j]) then inc(p);
			trank[sa[i]]:=p;
		end;
		for i:=1 to n do rank[i]:=trank[i];
		j:=j shl 1;
	end;
	for i:=1 to n do write(sa[i],' ');
	writeln;
	i:=sa[rank[1]-1];
	j:=0;
	while s[i+j]=s[1+j] do inc(j);
	height[rank[1]]:=j;
	for i:=2 to n do
	begin
		if j>0 then dec(j);
		k:=sa[rank[i]-1];
		while (s[k+j])=(s[i+j]) do inc(j);
		height[rank[i]]:=j;
	end;
	for i:=1 to n do write(height[i],' ');
end;
begin
	main;
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值