All X
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1318 Accepted Submission(s): 594
Problem Description
F(x,m)
代表一个全是由数字
x
组成的
m
位数字。请计算,以下式子是否成立:
F(x,m) mod k ≡ c
F(x,m) mod k ≡ c
Input
第一行一个整数
T
,表示
T
组数据。
每组测试数据占一行,包含四个数字 x,m,k,c
1≤x≤9
1≤m≤1010
0≤c<k≤10,000
每组测试数据占一行,包含四个数字 x,m,k,c
1≤x≤9
1≤m≤1010
0≤c<k≤10,000
Output
对于每组数据,输出两行:
第一行输出:"Case #i:"。 i 代表第 i 组测试数据。
第二行输出“Yes” 或者 “No”,代表四个数字,是否能够满足题目中给的公式。
第一行输出:"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: YesHint对于第一组测试数据:111 mod 5 = 1,公式不成立,所以答案是”No”,而第二组测试数据中满足如上公式,所以答案是 “Yes”。
我采用的矩阵二分幂来做
F[i] = (F[i-1]+x)%k
矩阵方程为
F[i] = 10 1 = F[i-1]
x 0 1 x
然后就是套路模版了
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct node{
int a[5][5];
}A;
node mul(node a,node b,LL mod){ ///矩阵乘法
node ans;
for(int i = 1;i <= 2;i++){
for(int j = 1; j <= 2;j++){
int tmp = 0;
for(int k = 1;k <= 2;k++){
tmp = (tmp+(a.a[i][k]*b.a[k][j])%mod)%mod;
ans.a[i][j] = tmp;
}
}
}
return ans;
}
node Pow(LL m,LL mod){ ///二分幂
node ret;
memset(ret.a,0,sizeof ret.a);
ret.a[1][1] = 1;ret.a[2][2] = 1;
while(m){
if(m&1) ret = mul(ret,A,mod);
A = mul(A,A,mod);
m /= 2;
}
return ret;
}
int main(void)
{
LL x,m,k,c;
int T;
scanf("%d",&T);
int times = 1;
while(T--){
scanf("%I64d%I64d%I64d%I64d",&x,&m,&k,&c);
A.a[1][1] = 10;A.a[1][2] = 1; ///系数矩阵
A.a[2][1] = 0; A.a[2][2] = 1;
node tmp;
tmp.a[1][1] = 0;tmp.a[1][2] = 0;
tmp.a[2][1] = x;tmp.a[2][2] = 0;
A = Pow(m,k);
tmp = mul(A,tmp,k);
printf("Case #%d:\n",times++);
if((tmp.a[1][1]%k) == c) puts("Yes");
else puts("No");
}
return 0;
}