• hdu 4552 怪盗基德的挑战书


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4552

    思路:

    其实可以用KMP+DP解决

    我这里给出后缀数组的解题方法

    思路:

    初始化ans=n(n为字符串的长度)

    然后你会发现答案就是ans加上每个后缀与最长后缀的最长公共前缀的长度

    代码:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 #define maxn 100010
     7 int wa[maxn],wv[maxn],wb[maxn],wq[maxn];
     8 int height[maxn],rank[maxn],sa[maxn];
     9 int r[maxn];
    10 char s[maxn];
    11 int n;
    12 int cmp(int *r,int a,int b,int l)
    13 {
    14     return r[a]==r[b]&& r[a+l]==r[b+l];
    15 }
    16 void da(int n,int m)
    17 {
    18     int i,j,p,*x=wa,*y=wb,*t;
    19     for(i=0;i<m;i++) wq[i]=0;
    20     for(i=0;i<n;i++) wq[x[i]=r[i]]++;
    21     for(i=1;i<m;i++) wq[i]+=wq[i-1];
    22     for(i=n-1;i>=0;i--) sa[--wq[x[i]]]=i;
    23 
    24     for(j=1,p=1;p<n;j*=2,m=p)
    25     {
    26        for(p=0,i=n-j;i<n;i++) y[p++]=i;
    27        for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    28        for(i=0;i<n;i++) wv[i]=x[y[i]];
    29        for(i=0;i<m;i++) wq[i]=0;
    30        for(i=0;i<n;i++) wq[wv[i]]++;
    31        for(i=1;i<m;i++) wq[i]+=wq[i-1];
    32        for(i=n-1;i>=0;i--) sa[--wq[wv[i]]]=y[i];
    33        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
    34                x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    35 
    36     }
    37     return ;
    38 }
    39 void callheight(int n)
    40 {
    41     int i,j,k=0;
    42     for(i=1;i<=n;i++) rank[sa[i]]=i;
    43     for(i=0;i<n;i++)
    44     {
    45         if(k)k--;
    46         j=sa[rank[i]-1];
    47         while(r[i+k]==r[j+k]) k++;
    48         height[rank[i]]=k;
    49     }
    50 }
    51 int main()
    52 {
    53  int Case=0;
    54  while(scanf("%s",s)!=EOF)
    55  {
    56      n=strlen(s);
    57      for(int i=0;i<n;i++)
    58              r[i]=s[i];
    59              r[n]=0;
    60      da(n+1,130);
    61      callheight(n);
    62      int ans=n;
    63      int t=rank[0];
    64      int temp=n;
    65      while(t<n)//加上排名在t后面的后缀与最长后缀的公共前缀长度
    66      {
    67          temp=min(temp,height[t+1]);
    68          ans+=temp;
    69          t++;
    70      }
    71      t=rank[0];
    72      temp=n;
    73      while(t>1)//加上排名在t前面的后缀与最长后缀的公共前缀的长度
    74      {
    75 
    76          temp=min(temp,height[t]);
    77          ans+=temp;
    78          t--;
    79      }
    80      cout<<ans%256<<endl;
    81  }
    82  return 0;
    83 }
    View Code
  • 相关阅读:
    js技巧收集(200多个)
    Ajax跨域访问的问题?
    最新软件下载提供列表
    美食家家V1.1[强力推荐]
    吉他和弦帮手以及曲子下载
    网译(在线中文英语翻译软件)[强力推荐]
    网上电子婚宴请柬
    吉他和弦帮手v2.3注册机
    1万多个英语单词mp3下载
    菜谱大全数据库下载(ACCESS)
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu4552.html
Copyright © 2020-2023  润新知