zoukankan      html  css  js  c++  java
  • bzoj 2528: [Poi2011]Periodicity【kmp+构造】

    神仙构造,做不来做不来
    详见:http://vfleaking.blog.163.com/blog/static/174807634201329104716122/

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=200005;
    int T,n,ne[N],p[N],cnt,a[N],I,J;
    char s[N];
    void get()
    {
        while(1)
        {
            if(J==0||a[I]==a[J])
            {
                I++;J++;
                ne[I]=J;
                break;
            }
            else
                J=ne[J];
        }
    } 
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",s+1);
            n=strlen(s+1);
            int i=1,j=0;
            ne[1]=0;
            while(i<=n)
            {
                if(j==0||s[i]==s[j])
                {
                    i++;j++;
                    ne[i]=j;
                }
                else j=ne[j];
            }
            i=n+1;
            cnt=0;
            while(i!=1)
            {
                cnt++;
                p[cnt]=i-1;
                i=ne[i];
            }
            for(int i=1;i<=cnt/2;i++)
                swap(p[i],p[cnt+1-i]);
            I=2;J=1;
            if(p[1]==1) 
                a[1]=0;
            else
            {
                a[1]=0;
                for(int i=2;i<p[1];i++) 
                    a[i]=0,get();
                a[p[1]]=1,get();
            }
            for(int i=2;i<=cnt;i++)
            {
                if(p[i]<=2*p[i-1])
                {
                    for(int j=p[i-1]+1;j<=p[i];j++)
                        a[j]=a[j-p[i]+p[i-1]],get();
                }
                else
                {
                    for(int j=p[i-1]+1;j<p[i]-p[i-1];j++)
                        a[j]=0,get();
                    int ii=I,jj=J;
                    a[p[i]-p[i-1]]=0;get();
                    if(ne[I]!=1&&(p[i]-p[i-1])%(I-ne[I])==0)
                    {
                        I=ii;J=jj;
                        a[p[i]-p[i-1]]=1;
                        get();
                    }
                    for(int j=p[i]-p[i-1]+1;j<=p[i];j++)
                        a[j]=a[j-p[i]+p[i-1]],get();
                }
            }
            for(i=1;i<=n;i++)
                printf("%d",a[i]);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    接水问题
    几种走法
    过河卒

    计数问题
    Java和C或C++的数据类型对照表
    记一次在家办公远程公司数据库的解决方案
    java nio 笔记
    mysql绿色版安装 遇到的问题
    mysql绿色版安装
  • 原文地址:https://www.cnblogs.com/lokiii/p/9507861.html
Copyright © 2011-2022 走看看