HDU 5690 查找循环节 数学公式快速幂+乘法逆元(除法取模)

来源:互联网 发布:centos gcc安装包下载 编辑:程序博客网 时间:2024/06/06 03:08

方法一 :因为m为10^10 次方,很大,所以猜测应该会出现循环节,

于是找到循环节映射出来即可

方法二:

m个x组成的数可以表示为x*(1+10+10^2+...+10^m-1)=x*(10^m-1)/9;
x*(10^m-1)/9%k==c     x*(10^m-1)%(9*k)==9*c

用快速幂去做去做。


#include<cstdio>#include<cstring>#include<iostream>#define LL long long#define INF 0x3f3f3f3f#define bug puts("**********");using namespace std;int  vis2[200000];int  vis[1100000];int main(){    LL x,m,k,c;    int t;    scanf("%d",&t);    for(int cas=1; cas<=t; cas++)    {        scanf("%lld%lld%lld%lld",&x,&m,&k,&c);        LL sum=0;        memset(vis2,-1,sizeof(vis2));        int start=-1,bit=0;        printf("Case #%d:\n",cas);        for(int i=0; i<m; i++)        {            sum=(sum*10+x)%k;            vis[i]=sum;            if(vis2[sum]!=-1)        ///寻找循环节            {                start=vis2[sum];    ///  循环开始的下标                bit=i-start;         ///循环长度                break;            }            vis2[sum]=i;        }        if(start==-1)          ///未出现循环节        {            if(sum%k==c)                puts("Yes");            else                puts("No");        }        else                  ///出现循环节        {            if(m-1>=start)     ///判断是否到达了循环的部分            {                        if(vis[(m-start-1)%bit+start]==c)    ///哈希得到值                    puts("Yes");                else                    puts("No");            }            else            {                if(vis[m]==c)                    puts("Yes");                else                    puts("No");            }        }    }    return 0;}


0 0