zoukankan      html  css  js  c++  java
  • [POJ2406]Power Strings

    传送门

    给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的,求 R 的最大值。

    1.后缀数组

    做法比较简单,穷举字符串 S 的长度 k,然后判断是否满足。判断的时候,

    先看字符串 L 的长度能否被 k 整除,再看 suffix(1)和 suffix(k+1)的最长公共

    前缀是否等于 n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以 RMQ 问题没有必要做所有的预处理,只需求出 height 数组中的每一个数到

    height[rank[1]]之间的最小值即可。

    因为用的是倍增求后缀数组,TLE,然而不会 DC3,正确性。。。。不知道(但至少思路是对的,你敢质疑罗大牛?)

    ——代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define N 1000001
     5 #define min(x, y) ((x) < (y) ? (x) : (y))
     6 
     7 int len, n, m, ans;
     8 int buc[N], x[N], y[N], sa[N], rank[N], height[N], d[N];
     9 char s[N];
    10 
    11 inline void build_sa()
    12 {
    13     int i, k, p;
    14     for(i = 0; i < m; i++) buc[i] = 0;
    15     for(i = 0; i < len; i++) buc[x[i] = s[i]]++;
    16     for(i = 1; i < m; i++) buc[i] += buc[i - 1];
    17     for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;
    18     for(k = 1; k <= len; k <<= 1)
    19     {
    20         p = 0;
    21         for(i = len - 1; i >= len - k; i--) y[p++] = i;
    22         for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
    23         for(i = 0; i < m; i++) buc[i] = 0;
    24         for(i = 0; i < len; i++) buc[x[y[i]]]++;
    25         for(i = 1; i < m; i++) buc[i] += buc[i - 1];
    26         for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];
    27         std::swap(x, y);
    28         p = 1, x[sa[0]] = 0;
    29         for(i = 1; i < len; i++)
    30             x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
    31         if(p >= len) break;
    32         m = p;
    33     }
    34 }
    35 
    36 inline void build_height()
    37 {
    38     int i, j, k = 0;
    39     for(i = 0; i < len; i++) rank[sa[i]] = i;
    40     for(i = 0; i < len; i++)
    41     {
    42         if(!rank[i]) continue;
    43         if(k) k--;
    44         j = sa[rank[i] - 1];
    45         while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
    46         height[rank[i]] = k;
    47     }
    48 }
    49 
    50 inline void RMQ_init()
    51 {
    52     int i, k;
    53     k = rank[0], d[k] = len;
    54     for(i = k - 1; i >= 0; i--) d[i] = min(d[i + 1], height[i + 1]);
    55     for(i = k + 1; i < len; i++) d[i] = min(d[i - 1], height[i]);
    56 }
    57 
    58 inline int RMQ(int k)
    59 {
    60     return d[rank[k]];
    61 }
    62 
    63 inline int solve()
    64 {
    65     int i;
    66     for(i = 1; i <= len / 2; i++)
    67         if(!(len % i))
    68             if(RMQ(i) == (len - i))
    69                 return len / i;
    70     return 1;
    71 }
    72 
    73 int main()
    74 {
    75     while(scanf("%s", s) && s[0] ^ '.')
    76     {
    77         m = 256;
    78         len = strlen(s);
    79         build_sa();
    80         build_height();
    81         RMQ_init();
    82         printf("%d
    ", solve());
    83     }
    84     return 0;
    85 }
    View Code

    可见后缀数组并不是正解。

    2.kmp(没细致研究过,以后补)

  • 相关阅读:
    发现个atan2的正确使用方式
    Forward+ Shading架构
    fatal: unable to connect to gitee.com: gitee.com[0: 180.97.125.228]: errno=Unknown error 解决方案
    HDFS HA(高可用性)集群规划
    如何使用RTP引擎对语音编码进行转码
    关于 Angular 应用 tsconfig.json 中的 target 属性
    浅谈 Orbeon form builder 的权限控制
    关于 Angular 应用 tsconfig.json 中的 lib 属性
    orbeon form 通过 url 的方式同第三方应用集成的开发明细
    orbeon form 的配置介绍
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6991038.html
Copyright © 2011-2022 走看看