P1050 循环

· · 题解

题意

给定两整数 n,k,求 n 的正整数次幂的最后 k 位的循环长度,若循环不存在输出 -1

1\le n\le 10^{100},1\le k \le 100

题解

这篇题解是对最高赞题解的补充与说明

在看最高赞题解的时候,因为没有放上计算过程,我对着题解手玩了好久才弄明白,所以就有了这篇附上计算过程的题解。

手玩数据 198123 4,因为要求只取后 4 位,所以将其截取成 8123

我们逐位进行处理:

记得判断无解的情况:如果在处理某一位时,乘了乘数 10 次,还是没有出现循环,无解。

8123               1
8123*8123=65983129 2
3129*8123=25416867 3
6867*8123=55780641 4
0641*8123=05206843 #
8123^4=4353773312630641

8123               1
8123*0641=05206843 2
6843*0641=04386363 3
6363*0641=04078683 4
8683*0641=05565803 5
5803*0641=03719723 #
0641^5=108215668739201

8123               1
8123*9201=74739723 2
9723*9201=89461323 3
1323*9201=12172923 4
2923*9201=26894523 5
4523*9201=41616123 #
9201^5=65943979755726446001

8123               1
8123*6001=48746123 2
6123*6001=36744123 3
4123*6001=24742123 4
2123*6001=12740123 5
0123*6001=00738123 #

ans=4*5*5*5=500

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int k;
char str[205];
struct bignum
{
    int x[205];
    bignum(){memset(x,0,sizeof(x));}
}n,tmp,mul,ans;
bignum operator *(bignum a,bignum b)//特化过的高精乘 只取后k位
{
    bignum ans;
    for(int i=0;i<k;i++)
        for(int j=0;j<k;j++)
            ans.x[i+j]+=a.x[i]*b.x[j];
    for(int i=0;i<k;i++)ans.x[i+1]+=ans.x[i]/10,ans.x[i]%=10;
    for(int i=k;i<205;i++)ans.x[i]=0;
    return ans;
}
bignum operator *(bignum a,int b)//这个高精乘低精是ans专用的233
{
    for(int i=0;i<=200;i++)a.x[i]*=b;
    for(int i=0;i<=200;i++)a.x[i+1]+=a.x[i]/10,a.x[i]%=10;
    return a;
}
int main()
{
    scanf("%s %d",str,&k);
    ans.x[0]=1;
    int len=strlen(str);
    for(int i=0;i<k;i++)
        n.x[i]=str[len-i-1]-'0';
    mul=n;
    for(int i=0;i<k;i++)
    {
        bignum tmp=n;
        int j=1,flag=1;
        for(j=1;j<=10;j++)
        {
            tmp=tmp*mul;
            if(tmp.x[i]==n.x[i])
            {
                ans=ans*j;
                flag=0;
                break;
            }
        }
        if(flag)
            return puts("-1"),0;
        tmp=mul;
        for(int k=1;k<j;k++)
            mul=mul*tmp;
    }
    len=200;
    while(ans.x[len]==0&&len>=1)len--;
    for(;len>=0;len--)putchar(ans.x[len]+'0');
}