码迷,mamicode.com
首页 > 编程语言 > 详细

【BZOJ1031】字符加密Cipher(后缀数组)

时间:2017-02-16 22:44:47      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:set   div   boolean   ++   粘贴   function   input   后缀数组   var   

题意:将一个长度为2n(复制粘贴后)的字符串的所有长度为n的后缀从小到大排序,并依次输出它们的最后一个字母。

n<=100000

思路:裸SA,模板真难背

P党不得不写成C++风格

 1 var ch:array[0..300000]of char;
 2     a,x,y,wc,wd,sa:array[0..300000]of longint;
 3     n,i,m:longint;
 4     tmp:char;
 5  
 6 function cmp(a,b,l:longint):boolean;
 7 begin
 8  exit((y[a]=y[b])and(y[a+l]=y[b+l]));
 9 end;
10  
11 procedure swap(var x,y:longint);
12 var t:longint;
13 begin
14  t:=x; x:=y; y:=t;
15 end;
16  
17 procedure getsa;
18 var i,j,p:longint;
19 begin
20  for i:=0 to n-1 do
21  begin
22   x[i]:=a[i];
23   inc(wc[a[i]]);
24  end;
25  for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
26  for i:=n-1 downto 0 do
27  begin
28   dec(wc[x[i]]);
29   sa[wc[x[i]]]:=i;
30  end;
31  
32  j:=1; p:=1;
33  while p<n do
34  begin
35   p:=0;
36   for i:=n-j to n-1 do
37   begin
38    y[p]:=i; inc(p);
39   end;
40   for i:=0 to n-1 do
41    if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
42  // for i:=0 to n-1 do writeln(y[i]);
43   for i:=0 to n-1 do wd[i]:=x[y[i]];
44   for i:=0 to m do wc[i]:=0;
45   for i:=0 to n-1 do inc(wc[wd[i]]);
46   for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
47   for i:=n-1 downto 0 do
48   begin
49    dec(wc[wd[i]]);
50    sa[wc[wd[i]]]:=y[i];
51   end;
52  
53   for i:=0 to n do swap(x[i],y[i]);
54  
55   p:=1; x[sa[0]]:=0;
56   for i:=1 to n-1 do
57   begin
58    if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1
59     else begin x[sa[i]]:=p; inc(p); end;
60   end;
61  
62   j:=j*2;
63   m:=p;
64  end;
65 end;
66  
67  
68 begin
69   assign(input,bzoj1031r.in); reset(input);
70   assign(output,bzoj1031r.out); rewrite(output);
71  while not eoln do
72  begin
73   read(tmp);
74   inc(n);
75   ch[n]:=tmp;
76  end;
77  for i:=1 to n do a[i-1]:=ord(ch[i]);
78  for i:=n to n*2-1 do a[i]:=a[i-n];
79  n:=n*2+1; m:=300;
80  getsa;
81  for i:=1 to n-1 do
82   if sa[i]<(n>>1) then
83   begin
84    if sa[i]=0 then write(chr(a[n-2]))
85     else write(chr(a[sa[i]-1]));
86   end;
87  close(input);
88 close(output);
89  
90  
91 end.

 

【BZOJ1031】字符加密Cipher(后缀数组)

标签:set   div   boolean   ++   粘贴   function   input   后缀数组   var   

原文地址:http://www.cnblogs.com/myx12345/p/6407261.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!