您的位置:首页 > 其它

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

2016-05-21 19:42 531 查看
方法一 :因为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: