作为线下选手,非常不要脸的写一份题解……
A、hdu5690
题意:求m个x组成的数模k是否等于c
m<=10^10,k<=10000
题解:两种做法,
第一种,裸的矩阵乘法,构造矩阵
{f(x,i),x}*{10 0}={f(x,i+1),x}
{1 1}
复杂度O(Tlog m)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int T;
int x,mod,C;
long long m;
struct yts
{
int x,y;
int a[3][3];
yts operator*(yts b)
{
yts ans;
ans.x=x;ans.y=b.y;
memset(ans.a,0,sizeof(ans.a));
for (int i=1;i<=x;i++)
for (int j=1;j<=b.y;j++)
for (int k=1;k<=y;k++)
ans.a[i][j]=(ans.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
return ans;
}
}a,b,c;
int main()
{
scanf("%d",&T);
for (int j=1;j<=T;j++)
{
scanf("%d%I64d%d%d",&x,&m,&mod,&C);
printf("Case #%d:\n",j);
a.x=1;a.y=2;a.a[1][1]=0;a.a[1][2]=x;
b.x=2;b.y=2;b.a[1][1]=10;b.a[2][1]=1;b.a[1][2]=0;b.a[2][2]=1;
c.x=2;c.y=2;c.a[1][1]=c.a[2][2]=1;c.a[1][2]=c.a[2][1]=0;
while (m)
{
if (m&1) c=c*b;
b=b*b;
m>>=1;
}
a=a*c;
if (a.a[1][1]==C) printf("Yes\n"); else printf("No\n");
}
return 0;
}
第二种,找循环节
暴力找循环节,不过循环节的长度不确定,所以复杂度不保证。
如果哪位神犇能够证明循环节小于等于k的话,欢迎交流。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int T;
int x,mod,c;
int dep[10010];
long long m;
int main()
{
scanf("%d",&T);
for (int j=1;j<=T;j++)
{
scanf("%d%I64d%d%d",&x,&m,&mod,&c);
printf("Case #%d:\n",j);
memset(dep,0,sizeof(dep));
int now=0,cnt=0;
for (;m>0;)
{
now=(now*10+x)%mod;cnt++;m--;
if (!dep[now]) dep[now]=cnt;
else m%=(long long)(cnt-dep[now]);
}
if (now==c) printf("Yes\n"); else printf("No\n");
}
return 0;
}
<