题目
Problem Description
F(x,m)
代表一个全是由数字x组成的m位数字。请计算,以下式子是否成立:
F(x,m)modk≡c
Input
第一行一个整数T,表示T组数据。
每组测试数据占一行,包含四个数字
x,m,k,c
1≤x≤9
1≤m≤1010
0≤c<k≤10,000
Output
对于每组数据,输出两行:
第一行输出:”Case #i:”。i代表第i组测试数据。
第二行输出“
Yes
” 或者 “
No
”,代表四个数字,是否能够满足题目中给的公式。
Sample Input
3
1 3 5 2
1 3 5 1
3 5 99 69
Sample Output
Case #1:
No
Case #2:
Yes
Case #3:
Yes
Hint
对于第一组测试数据:111 mod 5 = 1,公式不成立,所以答案是” No ”,而第二组测试数据中满足如上公式,所以答案是 “ Yes ”。
分析
F(x,m)=F(x,m−1)∗10+m
F(x,0)=0
这样一个递推式显然可以用矩阵加速
[F(x,m),m]=[F(x,m−1),m]∗[10,01,1]
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 50000
using namespace std;
typedef pair<int,int>pii;
typedef pair<int,pii>pip;
long long T,x,m,k,c;
template<class T>
void Read(T &x){
char c;
bool f=0;
while(c=getchar(),c!=EOF){
if(c=='-')
f=1;
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
ungetc(c,stdin);
if(f)
x=-x;
return;
}
}
}
struct matrix{
int a[2][2];
matrix(int ){
memset(a,0,sizeof a);
for(int i=0;i<2;i++)
a[i][i]=1;
}
matrix(){
memset(a,0,sizeof a);
}
matrix operator*(const matrix &b)const{
matrix c;
int i,j,l;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(l=0;l<2;l++)
c.a[i][j]=(c.a[i][j]+a[i][l]*b.a[l][j])%k;
return c;
}
void operator*=(const matrix &b){
*this=*this*b;
}
}a;
matrix quick_pow(matrix c,long long b){
matrix ret(m),a(c);
while(b){
if(b&1)
ret*=a;
a*=a;
b>>=1;
}
return ret;
}
void read(){
Read(x),Read(m),Read(k),Read(c);
}
void solve(){
a.a[0][0]=10,a.a[0][1]=0;
a.a[1][0]=1,a.a[1][1]=1;
a=quick_pow(a,m);
if(x*a.a[1][0]%k==c)
puts("Yes");
else
puts("No");
}
int main()
{
Read(T);
int cnt=0;
while(T--){
printf("Case #%d:\n",++cnt);
read();
solve();
}
}