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(没细致研究过,以后补)

  • 相关阅读:
    2.1 CDN Bypass
    4.1 SQL Injection
    ztosec/secscan-authcheck 安装部署教程
    浏览器的内部构造
    左右值的概念
    网络安全学习路线
    Python+Typora博客图片上传
    微信欢乐五子棋辅助
    [SUCTF 2019]EasySQL
    [护网杯 2018]easy_tornado (SSTI)
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6991038.html
Copyright © 2011-2022 走看看