zoukankan      html  css  js  c++  java
  • 51nod 1554 KMP思维题

    题目为中文,因而不再解释题意。

    首先遵循如下设定可以有以下几个结论:
    1,首先谈论下KMP的一个特殊性质:对于某一个特立独行的字符串:例如ABCDEF,在建立有限状态自动机之后,都会有,所有元素的失配边,指向0,也就是初始的那个元素。此时我们可以讲这个独立的元素及之前字符串理解为“ 一个循环次数为1的循环串 ”。对于其他情况,形如:ABCDEFGAB,可以将ABCDEFG理解为一个循环串,AB为下一个循环的两个多余元素,因此,我们可以把任意字符串看成“ 一个循环串+若干独立元素 ”的巧妙形式。

    2,对于该形式,都可以发现,对于第K号元素最小循环节的尺寸应当为“ K-F[K] ”(随着规约不同增减1,此处采用刘汝佳蓝书中KMP的规约),那么,我们可以在这个基础上求出来“最小循环节”循环的次数——K/(K-F[K])。

    3,应当认为,任意一个串,都构成(AB)*N+A的的形式。区别仅仅在于N的取值

    4,应当认为,任何一个循环串,形如(A+B)*N,都自然的可以被认为是(A+B+A+B)*N+(A+B)*k的形式,即可以将若干个相同的循环节看成一个大的循环节。

    5,前文中,我们知道了,“如何求出循环串的最小循环节”,以及“最小循环节的长度”,从而可以求出“最小循环节出现的次数”。则对于给定目标m来说,很容易求出,满足有且仅有M个大循环节时,每个大循环节的 “  最小循环体数量    ”,同时,也可以求出来,在满足上述条件后,“ 剩余的循环体数量 ”容易理解,在任何情况下,剩余的循环体数量大于最小循环体数量则构成一个新的循环,意味着M+1明显不符合题设,应当直接排出。

    回过头来发现刘汝佳蓝书第一道练习例题就讲的是这个233333333333

    放AC代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    const long long MAXN=1000233;
    
    char tar[MAXN];
    long long f[MAXN];
    
    long long n,m;
    void init()
    {
        cin>>n>>m;
        cin>>tar;
        
        f[1]=0;f[0]=0;
        for(int i=1;i<n;++i)
        {
            int j=f[i];
            while(j&&tar[i]!=tar[j])j=f[j];
            f[i+1]= tar[i]==tar[j]? j+1:0;
        }
    }
    
    
    int main()
    {
        cin.sync_with_stdio(false);
        init();
        for(int i=1;i<=n;++i)
        {
            int val=i/(i-f[i]);
            if(i%(i-f[i]))
            {
                if(val/m>val%m)cout<<1;
                else cout<<0;
            }else 
            {
                if(val/m>=val%m)cout<<1;
                else cout<<0;
            }
        }
        
        return 0;
    }
  • 相关阅读:
    在普通类中调用service
    layui util 工具时间戳转换
    最大值
    药房管理
    线段树2
    线段树1
    Dijkstra
    最大值最小化
    图的M 着色问题
    取余运算
  • 原文地址:https://www.cnblogs.com/rikka/p/7417598.html
Copyright © 2011-2022 走看看