社区讨论
求助大佬
P3809【模板】后缀排序参与者 7已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mi7pncqt
- 此快照首次捕获于
- 2025/11/21 01:33 4 个月前
- 此快照最后确认于
- 2025/11/21 01:33 4 个月前
对比: 第一个点:

全 。
PASCAL// 后缀排序
Uses math;
Const total=1010; // 这个不在意
var
sa,tmp,num,pus,copy,area,place,bucket,ranking:array[-1..total] of longint;
reach,from,next,cnt:array[-1..total] of longint;
queue:array[-1..11,-1..total,-1..3] of longint;
rank:array[-1..total,-1..3] of longint;
lg:array[-1..30] of longint;
i,n,tot,tail,number,border:longint;
s:ansistring;
j:char;
procedure add(l,r:longint);
begin inc(tot); from[tot]:=l; reach[tot]:=r; next[tot]:=cnt[l]; cnt[l]:=tot; end;
procedure Radix;
var
i,j,l,k,maxn:longint;
s:string;
begin
maxn:=-maxlongint;
for i:=1 to tail do
begin
maxn:=max(pus[i],maxn); copy[i]:=pus[i]; place[i]:=i; ranking[copy[i]]:=maxlongint;
end; str(maxn,s);
for i:=1 to length(s) do
begin
for j:=0 to 9 do queue[j,0,0]:=0;
for j:=1 to tail do
begin
k:=pus[j] mod 10; pus[j]:=pus[j] div 10;
inc(queue[k,0,0]);
queue[k,queue[k,0,0],1]:=pus[j];
queue[k,queue[k,0,0],2]:=place[j];
end; k:=0;
for j:=0 to 9 do
for l:=1 to queue[j,0,0] do
begin
inc(k); pus[k]:=queue[j,l,1]; place[k]:=queue[j,l,2];
queue[j,l,1]:=0; queue[j,l,2]:=0;
end;
end;
// 去重开始
for i:=1 to tail do ranking[copy[i]]:=min(ranking[copy[i]],place[i]);
for i:=1 to tail do place[i]:=ranking[copy[i]];
end;
procedure Sort;
var i,j,k,l,maxn,number:longint;
begin
// 第一关键字排序开始
for i:=1 to n do inc(bucket[num[i]]);
for i:=1 to border do inc(bucket[i],bucket[i-1]); border:=0;
for i:=1 to n do begin rank[i,1]:=bucket[num[i]]; border:=max(border,rank[i,1]); end;
i:=0;
repeat
inc(i); tot:=0; number:=0;
// 清空数组开始
filldword(cnt,sizeof(cnt) div 4,maxlongint*2+1);
fillchar(bucket,sizeof(bucket),0);
fillchar(reach,sizeof(reach),0);
fillchar(from,sizeof(from),0);
fillchar(next,sizeof(next),0);
// 生成第二关键字开始
for k:=1 to n do rank[k,2]:=rank[k+lg[i],1];
// 第一关键字排序开始 (桶+链表)
for k:=1 to n do if bucket[rank[k,1]]>0 then add(bucket[rank[k,1]],k) else bucket[rank[k,1]]:=k;
// 第二关键字排序开始 (基数排序)
for k:=1 to border do
begin
if bucket[k]=0 then continue;
// 存储第二关键字开始
tail:=1; j:=cnt[bucket[k]]; pus[1]:=rank[bucket[k],2]; area[1]:=bucket[k];
while j<>-1 do begin inc(tail); area[tail]:=reach[j]; pus[tail]:=rank[reach[j],2]; j:=next[j]; end;
// 基数排序开始
Radix; maxn:=0;
// 统计答案开始
for j:=1 to tail do begin rank[area[j],1]:=place[j]+number; maxn:=max(maxn,rank[area[j],1]); end;
number:=maxn;
end;
until lg[i+1]>n;
end;
begin
filldword(rank,sizeof(rank) div 4,0);
for i:=1 to 25 do lg[i]:=1 << (i-1);
readln(s); n:=length(s); number:=0;
// 离散化开始
for j:='0' to '9' do begin inc(number); tmp[ord(j)]:=number; end;
for j:='A' to 'Z' do begin inc(number); tmp[ord(j)]:=number; end;
for j:='a' to 'z' do begin inc(number); tmp[ord(j)]:=number; end;
for i:=1 to n do num[i]:=tmp[ord(s[i])]; border:=total; Sort;
// for i:=1 to n do writeln(rank[i,1]);
// 统计答案开始
for i:=1 to n do sa[rank[i,1]]:=i;
for i:=1 to n do write(sa[i],' ');
end.
回复
共 7 条回复,欢迎继续交流。
正在加载回复...