妙用next数组打表求最小循环节len

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int len;
int n = 1000;
int next[10000];
int f[50000];
char s[50000];
int Pow(int a, int b)
{
    int res=1;
    while(b)
    {
        if(b&1)
            res=res*a%7;
        a=a*a%7;
        b>>=1;
    }
    return res;
}
void getnext()
{
    int j=0,k=-1;
    next[0]=-1;
    while(j<n)
    {
        if(k==-1||s[j]==s[k])
        {
            next[++j]=++k;
        }
        else
        {
            k=next[k];
        }
    }
}
int main()
{
    for(int i=1;i<=600;i++)
    {
        f[i] = f[i-1] + Pow(i,i);
        f[i]%=7;
    }
    for(int i=0;i<=600;i++)
    {
        sprintf(&s[i],"%d",f[i]);
    }
    s[601]='\0';
    cout<<s<<endl;
    getnext();
    for(int i=1;i<=600;i++)          //由题意可知,长度为1的字符串不算
    {
        len=i-next[i];              //len代表最小循环节
        if(i%len==0 && i/len>1)      //周期大于1才是循环串
        {
            cout<<"ans = "<<len<<endl;
        }
    }
    printf("\n");
}

原文地址:https://www.cnblogs.com/Roni-i/p/9551463.html

时间: 2024-10-10 14:58:13

妙用next数组打表求最小循环节len的相关文章

hdu 3746 Cyclic Nacklace (KMP求最小循环节)

//len-next[len]为最小循环节的长度 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; char a[100010]; int next[100010]; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=len) { if(j==-1||a[i]==a[j]) i

The Minimum Length - HUST 1010(求最小循环节)

题意:有个一字符串A(本身不是循环串),然后经过很多次自增变成AAAAA,然后呢从自增串里面切出来一部分串B,用这个串B求出来A的长度.   分析:其实就是求最小循环节.......串的长度 - 最大的匹配. 代码如下. =========================================================================================================== #include<stdio.h> #include<

hdoj3746(kmp算法的nex数组求最小循环节)

题目链接:https://vjudge.net/problem/HDU-3746 题意:给定一个字符串,问最少在两端添加多少元素使得整个字符串是呈周期性的. 思路: 应用到kmp中nex数组的性质,数组的最小循环节是L=len-nex[len],证明见http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html. 如果len%L==0,那么输出0. 否则输出L-len%L. AC代码: #include<cstdio> #inclu

next数组求最小循环节

最小循环节(长度)=len-next[len]; 证明: ----------------------- ----------------------- k    m      x      j       i 由上,next[i]=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i] 设s[x...j]=s[j....i](xj=ji) 则可得,以下简写字符串表达方式 kj=kx+xj; mi=mj+ji; 因为xj=ji,所以kx=mj,如下图所示 ---

poj2406--Power Strings(KMP求最小循环节)

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 33178   Accepted: 13792 Description 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 = "

poj2185(kmp算法next数组求最小循环节,思维)

题目链接:https://vjudge.net/problem/POJ-2185 题意:给定由大写字母组成的r×c矩阵,求最小子矩阵使得该子矩阵能组成这个大矩阵,但并不要求小矩阵刚好组成大矩阵,即边界部分可以空缺(见样例). 思路: 把每一行视作一个字符,然后对r行求next数组,那么r-nex[r]即为以行为单元的最小循环节大小ans1. 把每一列视作一个字符,然后对c列求next数组,那么c-nex[c]即为以列为单元的最小循环节大小ans2. 最终答案即ans1*ans2.(子矩阵的面积)

Hdu 1358 Period (KMP 求最小循环节)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1358 题目描述: 给出一个字符串S,输出S的前缀能表达成Ak的所有情况,每种情况输出前缀的结束位置和k. 解题思路: 打表算出next数组,然后对位置i求循环节,如果满足 i % (i - Next[i]) == 0 && Next[i] != 0,所对应的循环节(i - Next[i]), 循环次数是i / (i - Next[i]) 1 #include<cstdio> 2

HDU 1358 (求最小循环节)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 题意:大概就是说给你一个字符串,然后找出能够循环的子串,输出子串某位置以及循环节的个数. 题解:用KMP算法得到next数组.然后,从i=2开始遍历,得到的i-next[i]为循环节大小. 如果对于i能够整除循环节,并且next数组的值不为0(如果为0,则代表不循环,但却可以整除) 则代表这个位置是可行的,位置为i,循环节个数为i/(i-next[i]) 代码如下: 1 #include<cs

HDU-1358 Period 字符串问题 KMP算法 求最小循环节

题目链接:https://cn.vjudge.net/problem/HDU-1358 题意 给一个字符串,对下标大于2的元素,问有几个最小循环节 思路 对每个元素求一下minloop,模一下就好 提交过程 TLE maxn没给够 AC 代码 #include <cstring> #include <cstdio> const int maxm=1e6+20; char P[maxm]; int fail[maxm]; void getFail(int m){ fail[0]=fa