• 51nod-1359: 循环探求


    【传送门:51nod-1359


    简要题意:

      给出n和k,求出最小的x满足$n^{x}≡n(mod;10^{k})$


    题解:

      真是一道有(du)趣(liu)题目

      首先我们设X[k-1]为$n^{x}≡n(mod;10^{k-1})$成立的最小的x

      那么我们就可以得到$n^{X[k-1]}≡n(mod;10^{k-1})$

      设$N[k-1]=n^{X[k-1]}$

      设t为任意值,可以发现$n^{t*X[k-1]}≡N[k-1]^{t}(mod;10^{k-1})$

      假设t*X[k-1]为满足$n^{x}≡n(mod;10^{k})$的最小的x的话,其实可以知道变的只有第k位,而第1到第k-1位仍然是不变的,那么我们对于一个k就枚举t,因为抽屉原理,所以N[k-1]^t的第k位最多只有10种情况,t枚举到12都仍未找到则说明不存在x,就直接输出1

      否则将得到的t连乘,最后+1就是答案了

      PS:为了不超时,高精度的时候要控制长度在k以内,不会影响结果


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    struct node
    {
        int a[2100],len;
        node()
        {
            len=0;
            memset(a,0,sizeof(a));
        }
    }N,d;
    char st[610];int k;
    node multi(node n1,node n2)
    {
        node no;no.len=k;
        for(int i=1;i<=k;i++)
        {
            for(int j=1;j+i-1<=k;j++) no.a[i+j-1]+=n1.a[i]*n2.a[j];
        }
        for(int i=1;i<=no.len;i++)
        {
            no.a[i+1]+=no.a[i]/10;
            no.a[i]%=10;
        }
        return no;
    }
    node solve(node n1,int n2)
    {
        node no;no.len=n1.len;
        for(int i=1;i<=no.len;i++) no.a[i]=n1.a[i]*n2;
        for(int i=1;i<=no.len;i++)
        {
            no.a[i+1]+=no.a[i]/10;
            no.a[i]%=10;
        }
        int i=no.len;
        while(no.a[i+1]>0)
        {
            i++;
            no.a[i+1]+=no.a[i]/10;
            no.a[i]%=10;
        }
        no.len=i;
        return no;
    }
    int main()
    {
        scanf("%s%d",st+1,&k);
        int len=strlen(st+1);N.len=len;
        for(int i=1;i<=len;i++) N.a[i]=st[len-i+1]-'0';
        d.a[1]=1;d.len=1;
        node B=N,p,x;
        for(int i=1;i<=k;i++)
        {
            int t=1;
            x=B;
            while(t<=11)
            {
                p=multi(N,B);
                if(p.a[i]==N.a[i]) break;
                B=multi(B,x);t++;
            }
            if(t>11){printf("1
    ");return 0;}
            d=solve(d,t);
        }
        d.a[1]++;
        for(int i=1;i<=d.len;i++)
        {
            d.a[i+1]+=d.a[i]/10;
            d.a[i]%=10;
        }
        int i=d.len;
        while(d.a[i+1]>0)
        {
            i++;
            d.a[i+1]+=d.a[i]/10;
            d.a[i]%=10;
        }
        d.len=i;
        for(int i=d.len;i>=1;i--) printf("%d",d.a[i]);
        printf("
    ");
        return 0;
    }

     

  • 相关阅读:
    net.sf.fmj.media.cdp.civil.CaptureDevicePlugger addCaptureDevices解决方法
    SVN快速入门教程
    Struts 2详细工作流程
    未能加载.NET基类问题
    图片上传的例子
    一个.NET发邮件的简单例子
    一种巧妙的删除程序自己的方法
    oracle的问题
    javascript 中对Trim()的实现
    SQL Server 不存在或访问被拒绝的问题
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9796765.html
Copyright © 2020-2023  润新知