HDU 5690——All X——————【快速幂 | 循环节】
All X
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 879 Accepted Submission(s): 421
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:
Yes
Hint
对于第一组测试数据:111 mod 5 = 1,公式不成立,所以答案是”No”,而第二组测试数据中满足如上公式,所以答案是 “Yes”。
Source
解题思路:打表找循环节。
#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<string> #include<iostream> #include<queue> #include<stack> #include<map> #include<vector> #include<set> using namespace std; typedef long long LL; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R #pragma comment(linker, "/STACK:102400000,102400000") const int maxn = 1e5 + 300; const LL INF = 0x3f3f3f3f; typedef long long LL; typedef unsigned long long ULL; LL vis[maxn], a[maxn]; int main(){ LL x, m, k, c; int T, cas = 0; scanf("%d",&T); while(T--){ scanf("%lld%lld%lld%lld",&x,&m,&k,&c); memset(vis,0,sizeof(vis)); int nn = 0, le = 0, st = 1; LL cc; LL n = 0; for(int i = 1; ; i++){ n = n*10; n = n + x; n = n%k; if(vis[n]){ cc = n; break; }else{ vis[n] = 1; nn++; a[nn] = n; } } for(int i = 1; i <= nn; i++){ if(a[i] == cc){ le = nn+1 - i; st = i; break; } } int flag = 0; if(m < st){ if(a[m] == c){ flag = 1; } }else{ m -= st; m %= le; if(a[st+m] == c){ flag = 1; } } printf("Case #%d:\n",++cas); if(flag) puts("Yes"); else puts("No"); } return 0; } /* 55 3 5 99 69 3 4 4 2 3 8 4 2 2 8 3 2 */
解题思路:数学方法。
转自http://m.blog.csdn.net/article/details?id=51471639
这个数要mod k ,那这个数应该怎么表示呢?
就这样转化了,然后10^m可以通过快速幂解决,但是很明显,除以9操作怎么办,除法取模,余数是会改变的,逆元?但是9和k不一定互质,且k也不一定是质数,所以扩展欧几里得和费马小定理都不能用了,束手无策
好吧,这里提供一种小方法
就这样经过几步转化,我求d不需要进行除法取模了,那我上面的问题不就解决了?对的。
#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<string> #include<iostream> #include<queue> #include<stack> #include<map> #include<vector> #include<set> using namespace std; typedef long long LL; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R #pragma comment(linker, "/STACK:102400000,102400000") const int maxn = 1e5 + 300; const LL INF = 0x3f3f3f3f; typedef long long LL; typedef unsigned long long ULL; LL quick(LL x,LL n,LL p){ if(n == 0) return 1; LL ret = 1; while(n){ if(n&1) ret = ret*x % p; n = n >> 1; x = x*x % p; } return ret; } int main(){ LL x, m, k, c; int T, cas = 0; scanf("%d",&T); while(T--){ scanf("%lld%lld%lld%lld",&x,&m,&k,&c); k*=9; LL ans = quick(10,m,k); ans = (ans - 1 + k) % k; ans /= 9; k /= 9; ans = ans * x % k; bool flag = 0; if(ans == c) flag = 1; printf("Case #%d:\n",++cas); if(flag) puts("Yes"); else puts("No"); } return 0; }
学学学 练练练 刷刷刷