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

https://www.cnblogs.com/njczy2010/p/3930688.html
https://blog.csdn.net/dominating413421391/article/details/44203019?locationNum=1&fps=1
https://blog.csdn.net/piekey1994/article/details/38436511 [数学]

#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");
}

#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
ll x[1005];
long mod(long a,long n,long b){    //a^b mod c
    long t;
    if(n==0) return 1%b;
    if(n==1) return a%b;
    t=mod(a,n/2,b);
    t=t*t%b;
    if((n&1)==1) t=t*a%b;
    return t;}
int main(){
	string s[7]={"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};

	x[0]=0;
	for(int i=1;i<=1000;++i)
		x[i]=(x[i-1]%7+mod(i,i,7))%7;
	int next[1001];
	next[0] = 0;
	int len=1000;
	for(int i = 1, q = 0; i < len; i++){ //x[]里放的是要找规律的数组
   	while(q > 0 && x[i] != x[q])
     		 q = next[q-1];
   		 if (x[i] == x[q])
    		    q++;
   		 next[i] = q;
   	 	 if (q != 0 && (i + 1) % (i + 1 - q) == 0){
     		     printf("%d\n", i+1-q);  //输出的就是最大循环长度
    	  		 break;
    	}
    }
	return 0;
}
posted @ 2018-08-28 22:43  Roni_i  阅读(192)  评论(0编辑  收藏  举报