• Codeforces


    D. Om Nom and Necklace
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    One day Om Nom found a thread with n beads of different colors. He decided to cut the first several beads from this thread to make a bead necklace and present it to his girlfriend Om Nelly.

    Om Nom knows that his girlfriend loves beautiful patterns. That's why he wants the beads on the necklace to form a regular pattern. A sequence of beads S is regular if it can be represented as S = A + B + A + B + A + ... + A + B + A, where A and B are some bead sequences, " + " is the concatenation of sequences, there are exactly 2k + 1 summands in this sum, among which there are k + 1 "A" summands and k "B" summands that follow in alternating order. Om Nelly knows that her friend is an eager mathematician, so she doesn't mind if A or B is an empty sequence.

    Help Om Nom determine in which ways he can cut off the first several beads from the found thread (at least one; probably, all) so that they form a regular pattern. When Om Nom cuts off the beads, he doesn't change their order.

    Input

    The first line contains two integers n, k (1 ≤ n, k ≤ 1 000 000) — the number of beads on the thread that Om Nom found and number k from the definition of the regular sequence above.

    The second line contains the sequence of n lowercase Latin letters that represent the colors of the beads. Each color corresponds to a single letter.

    Output

    Print a string consisting of n zeroes and ones. Position i (1 ≤ i ≤ n) must contain either number one if the first i beads on the thread form a regular sequence, or a zero otherwise.

    Sample test(s)
    Input
    7 2
    bcabcab
    Output
    0000011
    Input
    21 2
    ababaababaababaababaa
    Output
    000110000111111000011
    Note

    In the first sample test a regular sequence is both a sequence of the first 6 beads (we can take A = "", B = "bca"), and a sequence of the first 7 beads (we can take A = "b", B = "ca").

    In the second sample test, for example, a sequence of the first 13 beads is regular, if we take A = "aba", B = "ba".


    思路:可以将AB看成一个串(设为C),然后问题就等价为:判断字符串是否由k个连续的C串以及C串的一个前缀组成(前缀可以为空)。

    然后用Z算法求出z数组。

    然后从1到n枚举C串的长度(设为len),判断z[0],z[len],z[len*2],....,z[len*(k-1)]的值是否都不小于len,如果都符合就标记最后一个匹配位置为true。

    输出的时候维护一个last指针,表示C串的前缀最多能扩展到哪个位置。

    复杂度o(n).


     1 #include <iostream>
     2 #include <stdio.h>
     3 using namespace std;
     4 #define MAXN 1000010
     5 
     6 char s[MAXN];
     7 bool ans[MAXN] = {0};
     8 int z[MAXN] = {0};
     9 
    10 int n, k;
    11 bool check(int len)
    12 {
    13     for(int i = 0, cnt = 0; i < n && cnt < k; i += len, cnt++)
    14     {
    15         if(z[i] < len)
    16             return false;
    17     }
    18     return true;
    19 }
    20 
    21 int main()
    22 {
    23     freopen("in.txt", "r", stdin);
    24     cin >> n >> k;
    25 
    26     scanf("%s", s);
    27 
    28     // Z[i] is the length of the longest substring starting from S[i] which is also a prefix of S
    29     // s[0,n-1]
    30     int L = 0, R = 0;
    31     for(int i = 1; i < n; i++)
    32     {
    33         if(i > R)
    34         {
    35             L = R = i;
    36             while(R < n && s[R - L] == s[R]) R++;
    37             z[i] = R - L;
    38             R--;
    39         }
    40         else
    41         {
    42             int k = i - L;
    43             if(z[k] < R - i + 1) z[i] = z[k];
    44             else
    45             {
    46                 L = i;
    47                 while(R < n && s[R - L] == s[R]) R++;
    48                 z[i] = R - L;
    49                 R--;
    50             }
    51         }
    52     }
    53     z[0] = n;
    54 
    55 
    56     // 枚举AB串的长度
    57     for(int len = 1; len <= n; len++)
    58     {
    59         if(len * k > n)
    60             break;
    61         // 判断长度为len的AB串是否符合
    62         if(check(len))
    63         {
    64             int last = len * k;
    65             ans[last - 1] = true;
    66         }
    67     }
    68 
    69     int last = -1;
    70     for(int i = 0; i < n; i++)
    71     {
    72         if(ans[i] || i<=last)
    73             printf("1");
    74         else
    75             printf("0");
    76         if(ans[i] && i < n - 1)
    77         {
    78             int len = (i+1)/k;
    79             last = max(last, min(i+len, i+z[i+1]));
    80         }
    81     }
    82 
    83     return 0;
    84 }
  • 相关阅读:
    磁盘原理总结
    Algorithm:多维数组和矩阵
    Algorithm:字典序最小问题
    Algorithm:递归思想及实例分析
    Algorithm:贪心策略之区间覆盖问题
    Algorithm:贪心策略之区间选点问题
    Algorithm:位运算的这些小技巧你知道吗?
    面试题
    操作系统
    数据结构:B树和B+树的插入、删除图文详解
  • 原文地址:https://www.cnblogs.com/oneshot/p/4395273.html
Copyright © 2020-2023  润新知