• bzoj1031: [JSOI2007]字符加密Cipher(后缀数组)


    1031: [JSOI2007]字符加密Cipher

    题目:传送门

    正解:

       后缀数组裸题。。。

       刚开始看的时候可能觉得一个个排序很麻烦,其实在后面接多一个相同的字符串之后再跑一边sa就ok

       因为对于每一个组成顺序不同的字符串来说,其实长度都是一样的,这就保证了他们在这个长度的范围内就可以比较出大小。

       所以我们所做的预处理是没有影响的。

       输出的时候再稍微判断一下就AC了...有点水

    手撸模版:

       

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define N 1100000
     7 using namespace std;
     8 int Rank[N],Rsort[N],sa[N],y[N],wr[N];
     9 char s[N];
    10 int a[N];
    11 int len,n;
    12 bool cmp(int k1,int k2,int ln){return wr[k1]==wr[k2] && wr[k1+ln]==wr[k2+ln];}
    13 void get_sa(int n,int m)
    14 {
    15     memcpy(Rank,a,sizeof(Rank));
    16     
    17     memset(Rsort,0,sizeof(Rsort));
    18     for(int i=1;i<=n;i++)Rsort[Rank[i]]++;
    19     for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
    20     for(int i=n;i>=1;i--)sa[Rsort[Rank[i]]--]=i;
    21     
    22     int ln=1,k,p=0;
    23     while(p<n)
    24     {
    25         k=0;
    26         for(int i=n-ln+1;i<=n;i++)y[++k]=i;
    27         for(int i=1;i<=n;i++)if(sa[i]>ln)y[++k]=sa[i]-ln;
    28         
    29         for(int i=1;i<=n;i++)wr[i]=Rank[y[i]];
    30         
    31         memset(Rsort,0,sizeof(Rsort));
    32         for(int i=1;i<=n;i++)Rsort[wr[i]]++;
    33         for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
    34         for(int i=n;i>=1;i--)sa[Rsort[wr[i]]--]=y[i];
    35         
    36         for(int i=1;i<=n;i++)wr[i]=Rank[i];
    37         p=1;Rank[sa[1]]=1;
    38         for(int i=2;i<=n;i++)
    39         {
    40             if(!cmp(sa[i],sa[i-1],ln))p++;
    41             Rank[sa[i]]=p;
    42         }
    43         m=p;ln*=2;
    44     }
    45 }
    46 int main()
    47 {
    48     scanf("%s",s+1);len=strlen(s+1);
    49     n=len*2;int j=0;
    50     for(int i=len+1;i<=n;i++)s[i]=s[++j];
    51     for(int i=1;i<=n;i++)a[i]=s[i];
    52     get_sa(n,1000);
    53     for(int i=1;i<=n;i++)
    54     {
    55         if(sa[i]>len)continue;
    56         else
    57         {
    58             printf("%c",a[sa[i]+len-1]);
    59         }
    60     }
    61     printf("
    ");
    62     return 0;
    63 }
  • 相关阅读:
    Symmetric Tree
    Splunk的安装与使用
    【BZOJ2662】【BeiJing wc2012】冻结 分层图 裸的!
    Android NFC近场通信03----读写MifareClassic卡
    IOS把图片做成圆形效果
    【翻译自mos文章】CRS显示 正在执行的db instance 是offline状态
    远程訪问路由器下的mac os(ssh+vnc)
    POJ 2488 A Knight&#39;s Journey
    python 分词计算文档TF-IDF值并排序
    ExcelReader(解析Excel的工具类)
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8042650.html
Copyright © 2020-2023  润新知