zoukankan      html  css  js  c++  java
  • 【BZOJ1031】字符加密Cipher(后缀数组)

    题意:将一个长度为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.
  • 相关阅读:
    apicloud图片上传
    APICloud上啦加载下拉刷新模块
    APICloud 获取缓存以及清除缓存(常用第三方方法)
    微信小程序跳转以及跳转的坑
    微信小程序,时间戳和日期格式互相转化
    微信小程序template使用
    APICloud开发小技巧(二)
    javax.persistence.TransactionRequiredException: Executing an update/delete query
    Spring的注解@Qualifier用法
    Spring @Service生成bean名称的规则
  • 原文地址:https://www.cnblogs.com/myx12345/p/6407261.html
Copyright © 2011-2022 走看看