zoukankan      html  css  js  c++  java
  • ZOJ1905Power Strings (KMP||后缀数组+RMQ求循环节)

    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

    Input

    Each test case is a line of input representing s, a string of printable characters.


    <b< dd="">

    Output

    For each s you should print the largest n such that s = a^n for some string a. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

    Sample Input

    abcd
    aaaa
    ababab
    .

    Sample Output

    1
    4
    3

    求最大循环长度。

    KMP可以求,之前做过,见。

    http://www.cnblogs.com/hua-dong/p/8016873.html

    http://www.cnblogs.com/hua-dong/p/8016916.html

    这里实现了后缀数组(不过好像被卡了,只能同KMP实现)。

    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    int min(int x,int y) { if(x<y) return x;return y;}
    using namespace std;
    const int maxn=1000010;
    char ch[maxn];
    struct SA
    { 
        int Rank[maxn],sa[maxn],tsa[maxn],A[maxn],cntA[maxn],B[maxn],cntB[maxn];
        int ht[maxn],Min[maxn][30],N;
        void get_SA()
        {
            N=strlen(ch+1);
            for(int i=0;i<=300;i++) cntA[i]=0;
            for(int i=1;i<=N;i++)  cntA[ch[i]]++;
            for(int i=1;i<=300;i++) cntA[i]+=cntA[i-1];
            for(int i=N;i>=1;i--)  sa[cntA[ch[i]]--]=i;
            Rank[sa[1]]=1;
            for(int i=2;i<=N;i++)  Rank[sa[i]]=Rank[sa[i-1]]+(ch[sa[i]]==ch[sa[i-1]]?0:1);
            for(int l=1;Rank[sa[N]]<N;l<<=1){
                for(int i=1;i<=N;i++) cntA[i]=cntB[i]=0;
                for(int i=1;i<=N;i++) cntA[A[i]=Rank[i]]++;
                for(int i=1;i<=N;i++) cntB[B[i]=i+l<=N?Rank[i+l]:0]++;
                for(int i=1;i<=N;i++) cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];
                for(int i=N;i>=1;i--) tsa[cntB[B[i]]--]=i;
                for(int i=N;i>=1;i--) sa[cntA[A[tsa[i]]]--]=tsa[i];
                Rank[sa[1]]=1;
                for(int i=2;i<=N;i++) Rank[sa[i]]=Rank[sa[i-1]]+(A[sa[i]]==A[sa[i-1]]&&B[sa[i]]==B[sa[i-1]]?0:1);
            }
        }
        void get_hgt()
        {
            for(int i=1,j=0;i<=N;i++){
                if(j) j--;
                while(ch[i+j]==ch[sa[Rank[i]-1]+j]) j++;
                ht[Rank[i]]=j;
            }
        }
        void get_rmq()
        {
            for(int i=1;i<=N;i++) Min[i][0]=ht[i];
            for(int i=1;(1<<i)<=N;i++)
             for(int j=1;j+(1<<i)-1<=N;j++){
                  Min[j][i]=min(Min[j][i-1],Min[j+(1<<(i-1))][i-1]);
             }
        }
        int query_rmq(int L,int R)
        {
            if(L>R) swap(L,R);L++;
            int k=log2(R-L+1);
            return min(Min[L][k],Min[R-(1<<k)+1][k]);
        }
        void solve()
        {
            int ans=1;
            for(int i=1;i<=N;i++){
                if(N%i!=0) continue;
                if(i+query_rmq(Rank[1],Rank[1+i])==N) {
                    ans=N/i; break;
                }
            }   printf("%d
    ",ans);
        }
    }Sa;
    int main()
    {
        while(~scanf("%s",ch+1)){
            if(ch[1]=='.') return 0;
            Sa.get_SA();
            Sa.get_hgt();
            Sa.get_rmq();
            Sa.solve(); 
        }  return 0;
    }
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    密码学-学习笔记
    让MySQL速度提升3倍的19种优化方式
    Oracle/云MySQL/MsSQL“大迁移”真相及最优方案
    tf.TFRecordReader()函数解析(最清晰的解释)
    Polkadot(波卡)简介
    Gavin Wood的故事:神级黄皮书、出走以太坊、乱世成名与三代区块链
    从设计哲学对比波卡与Cosmos
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8151272.html
Copyright © 2011-2022 走看看