zoukankan      html  css  js  c++  java
  • The 15th UESTC Programming Contest Preliminary H

    地址:http://acm.uestc.edu.cn/#/problem/show/1551

    题目:

    Hesty Str1ng

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

    A chrysanthemum was painted on the second page, and we tried to use the magic power learned just now.

    The beautiful flower was compacted to a colorful string SS representing by characters for some simplifying reasons.

    As known, if we try to choose a substring AA of SS and concatenate it with an arbitrary non-empty string BB whose length is less than AA, we can get a new string TT.

    The poetry told us the key to the eternity living secret is the number of the distinct palindrome strings made by the method above.

    Two strings are considered different if and only if there are different characters in the same position of two strings.

    Input

    Only one line contains the string SS.

    SS is composed by lowercase English characters, 1|S|1000001≤|S|≤100000.

    Output

    The key to the eternity living secret.

    Sample input and output

    Sample InputSample Output
    abc
    3

    Hint

    The palindrome strings can be made are "aba", "bcb", "abcba".

    思路:

      对于一个长度为n的子串,如果在其后连接一个长度为x(1<=x<n)的字符串形成新串T,并且T为回文串。

      n=1时:形成的T的数量=0

      n>1时:形成的T的数量=1+sum.(sum:子串含有的不同回文后缀的数量)

      回顾下计算不同子串个数的后缀数组做法:

      

      下面先给出一个结论:

        sum[x]:表示后缀s[x....n-1]中s[k]==s[k+1]的个数

        ans=∑(n-sa[i]-height[i]+sum[sa[i]+height[i]]) (字符串下标从0开始。)

        并且当

           height[i]==0时  ans-=1;

           height[i]>=2&&ss[sa[i]+height[i]-1]==ss[sa[i]+height[i]]时  ans+=1;

           !height[i]&&ss[sa[i]+height[i]]==ss[sa[i]+height[i]+1]时  ans-=1;

        上面对应的三种情况分别是:

        1. 此时有排序后的后缀abbb,ba.

        2.  此时有排序后的后缀abb,abbba

        3. 此时有排序后的后缀a,bba

      具体证明过程我就不写了(PS:其实是我也不太会)

       参考自校队另一位dalao的博文:http://blog.csdn.net/prolightsfxjh/article/details/66970491

      具体见代码

        

     1 #include <cstdlib>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 
     6 const int N = 100005;
     7 int wa[N], wb[N], ws[N], wv[N];
     8 int s[N],sa[N],rank[N], height[N];
     9 char ss[N];
    10 int sum[N];
    11 bool cmp(int r[], int a, int b, int l)
    12 {
    13     return r[a] == r[b] && r[a+l] == r[b+l];
    14 }
    15 
    16 void da(int r[], int sa[], int n, int m)
    17 {
    18     int i, j, p, *x = wa, *y = wb;
    19     for (i = 0; i < m; ++i) ws[i] = 0;
    20     for (i = 0; i < n; ++i) ws[x[i]=r[i]]++;
    21     for (i = 1; i < m; ++i) ws[i] += ws[i-1];
    22     for (i = n-1; i >= 0; --i) sa[--ws[x[i]]] = i;
    23     for (j = 1, p = 1; p < n; j *= 2, m = p)
    24     {
    25         for (p = 0, i = n - j; i < n; ++i) y[p++] = i;
    26         for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
    27         for (i = 0; i < n; ++i) wv[i] = x[y[i]];
    28         for (i = 0; i < m; ++i) ws[i] = 0;
    29         for (i = 0; i < n; ++i) ws[wv[i]]++;
    30         for (i = 1; i < m; ++i) ws[i] += ws[i-1];
    31         for (i = n-1; i >= 0; --i) sa[--ws[wv[i]]] = y[i];
    32         for (std::swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
    33             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
    34     }
    35 }
    36 
    37 void calheight(int r[], int sa[], int n)
    38 {
    39     int i, j, k = 0;
    40     for (i = 1; i <= n; ++i) rank[sa[i]] = i;
    41     for (i = 0; i < n; height[rank[i++]] = k)
    42         for (k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);
    43 }
    44 
    45 int main()
    46 {
    47     int len;
    48     long long ans=0;
    49     scanf("%s",ss);
    50     len=strlen(ss);
    51     for(int i=0;i<len;i++)
    52         s[i]=ss[i]-'a'+1;
    53     s[len]=0;
    54     da(s,sa,len+1,28);
    55     calheight(s,sa,len);
    56     for(int i=len-1;i>=0;i--)
    57     if(ss[i]==ss[i+1])  sum[i]=sum[i+1]+1;
    58     else    sum[i]=sum[i+1];
    59     for(int i=1;i<=len;i++)
    60     {
    61         if(height[i]==0)ans--;
    62         ans+=sum[sa[i]+height[i]]+len-sa[i]-height[i];
    63         if(height[i]>=2&&ss[sa[i]+height[i]-1]==ss[sa[i]+height[i]])
    64             ans++;
    65         if(!height[i]&&ss[sa[i]+height[i]]==ss[sa[i]+height[i]+1])
    66             ans--;
    67         //printf("x==%d %lld
    ",i,ans);
    68     }
    69     printf("%lld
    ",ans);
    70     return 0;
    71 }

     

  • 相关阅读:
    Deep learning:二十五(Kmeans单层网络识别性能)
    Deep learning:三十六(关于构建深度卷积SAE网络的一点困惑)
    Matlab成长之路_5(解决out of memory问题)
    Deep learning:三(Multivariance Linear Regression练习)
    Deep learning:一(基础知识_1)
    Deep learning:三十二(基础知识_3)
    算法设计和数据结构学习_2(常见排序算法思想)
    Deep learning:二十七(Sparse coding中关于矩阵的范数求导)
    Deep learning:十二(PCA和whitening在二自然图像中的练习)
    总结系列_15(不能从u盘启动安装win7系统的一个小原因)
  • 原文地址:https://www.cnblogs.com/weeping/p/6640878.html
Copyright © 2011-2022 走看看