zoukankan      html  css  js  c++  java
  • 后缀数组 POJ 2406 Power Strings

    题目链接

    题意:连续重复子串。给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的(L = S^R ), 求 R 的最大值。

    分析:枚举长度,判断条件是能被总长度整除且LCP (suffix (0), suffix (i)) = n - i,预处理出lcp,方法是,lcp[i] = min (height[rank[i]] to height[rank[0]]); DC3算法,C++提交才能AC。

    #include<cstdio>
    #include<cstring>
    #include <algorithm>
    const int N = 2e6 + 5;
    #define F(x) ((x)/3+((x)%3==1?0:tb))
    #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
    int wa[N],wb[N],wv[N],ws[N];
    int rank[N],height[N];    
    int sa[N],r[N];
    char c[N];
    int lcp[N]; //记录到height[rank[0]]的最小值 
    
    int Min(int a,int b)
    {
        return a<b?a:b;
    }
    
    int c0(int *y,int a,int b)
    {
        return y[a]==y[b]&&y[a+1]==y[b+1]&&y[a+2]==y[b+2];
    }
    int c12(int k,int *y,int a,int b)
    {
        if(k==2) return y[a]<y[b]||y[a]==y[b]&&c12(1,y,a+1,b+1);
        else return y[a]<y[b]||y[a]==y[b]&&wv[a+1]<wv[b+1];
    }
    void sort(int *r,int *a,int *b,int n,int m)
    {
        int i;
        for(i=0;i<n;i++) wv[i]=r[a[i]];
        for(i=0;i<m;i++) ws[i]=0;
        for(i=0;i<n;i++) ws[wv[i]]++;
        for(i=1;i<m;i++) ws[i]+=ws[i-1];
        for(i=n-1;i>=0;i--) b[--ws[wv[i]]]=a[i];
        return;
    }
    void dc3(int *r,int *sa,int n,int m)
    {
        int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
        r[n]=r[n+1]=0;
        for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i;
        sort(r+2,wa,wb,tbc,m);
        sort(r+1,wb,wa,tbc,m);
        sort(r,wa,wb,tbc,m);
        for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)
            rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;
        if(p<tbc) dc3(rn,san,tbc,p);
            else for(i=0;i<tbc;i++) san[rn[i]]=i;
        for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3;
        if(n%3==1) wb[ta++]=n-1;
        sort(r,wb,wa,ta,m);
        for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i;
        for(i=0,j=0,p=0;i<ta && j<tbc;p++)
            sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];
        for(;i<ta;p++) sa[p]=wa[i++];
        for(;j<tbc;p++) sa[p]=wb[j++];
        return;
    }
    void calc_height(int n) {
        int i, k = 0;
        for (i=0; i<=n; ++i) rank[sa[i]] = i;
        for (i=0; i<n; ++i) {
            if (k) k--;
            int j = sa[rank[i]-1];
            while (r[i+k] == r[j+k]) k++;
            height[rank[i]] = k;
        }
    }
    
    int main() {
        while (scanf ("%s", c) != EOF) {
            if (strcmp (c, ".") == 0) {
                break;
            }
            int n = strlen (c);
            for (int i=0; i<n; ++i) {
                r[i] = c[i] + 1;
            }
            r[n] = 0;
            dc3 (r, sa, n + 1, 256);
            calc_height (n);
            
            memset (lcp, 0, sizeof (lcp));
            lcp[rank[0]] = N;
            for (int i=rank[0]-1; i>=0; --i) {
                lcp[i] = std::min (lcp[i+1], height[i+1]);
            }
            for (int i=rank[0]+1; i<=n; ++i) {
                lcp[i] = std::min (lcp[i-1], height[i]);
            }
            for (int i=1; i<=n; ++i) {
                if (n % i == 0 && lcp[rank[i]] == n - i) {
                    printf ("%d
    ", n / i);
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    Android 2.2 r1 API 中文文档系列(11) —— RadioButton
    Android API 中文 (15) —— GridView
    Android 中文 API (16) —— AnalogClock
    Android2.2 API 中文文档系列(7) —— ImageButton
    Android2.2 API 中文文档系列(6) —— ImageView
    Android 2.2 r1 API 中文文档系列(12) —— Button
    Android2.2 API 中文文档系列(8) —— QuickContactBadge
    [Android1.5]TextView跑马灯效果
    [Android1.5]ActivityManager: [1] Killed am start n
    Android API 中文(14) —— ViewStub
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5450056.html
Copyright © 2011-2022 走看看