hdu 5690(同余定理找循环节 / 快速幂)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define lld I64d
 5 #ifdef _WIN32
 6 #define LLD "%I64d"
 7 #else
 8 #define LLD "%lld"
 9 #endif
10 const int N = 10000 + 100;
11 ll x,m,c,k;
12 int pos[N];
13 /**
14  * 同余定理:
15  * (a+b) mod n = ((a mod n) + (b mod n)) mod n;
16  * ab mod n = (a mod n)*(b mod n) mod n;
17  *
18  *555 mod n = (550 + 5) mod n = 550 mod n + 5 mod n
19  *                              = ((55 mod n) * (10 mod n)     + 5 mod n) mod n;
20  *  g(i) mod n = (g(i-1) * 10 + 5) mod n;
21  *
22  * 记录上一个相同值出现的位置,求出循环节,然后使 i 逼近 m,
23  * tmp 继续 * 10 + x 直到 m;
24  * */
25 int main(){
26     int T,kase = 1;
27     scanf("%d",&T);
28     while(T--){
29         scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
30         memset(pos,-1,sizeof(pos));
31         ll tmp = 0;
32         ll d = 0 , now = 0;
33         for(int i = 1 ; i <= N; i ++){
34             tmp = (tmp * 10 + x) % k; // 同余定理
35             if(pos[tmp] == -1){
36                 pos[tmp] = i;
37             }else{
38                 d = i - pos[tmp];
39                 now = i;
40                 break;
41             }
42         }
43         ll ansn = now + (m - now) / d * d;
44         if(ansn > m) ansn -= d;
45         while(++ansn <= m){
46             tmp = (tmp * 10 + x) % k;
47         }
48         if(tmp == c){
49             printf("Case #%d:\nYes\n",kase++);
50         }else{
51             printf("Case #%d:\nNo\n",kase++);
52         }
53     }
54 }

快速幂:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define lld I64d
 5 ll x,m,c,k;
 6 ll quickmod(ll a,ll b,ll mod){
 7     ll ret = 1;
 8     while(b){
 9         if(b & 1) ret = ret*a % mod;
10         a = a*a % mod;
11         b >>= 1;
12     }
13     return ret;
14 }
15 int main(){
16     int T,kase = 1;
17     scanf("%d",&T);
18     while(T--){
19         scanf("%lld%lld%lld%lld",&x,&m,&k,&c);
20         ll mod = 9*k;
21         ll ret = quickmod(10,m,mod);
22         if((ret%mod-1%mod)*(x%mod)%mod == 9*c){
23 //        if(ret*x%mod - x%mod == 9*c){
24             printf("Case #%d:\nYes\n",kase++);
25         }else{
26             printf("Case #%d:\nNo\n",kase++);
27         }
28     }
29     return 0;
30 }
31 /**
32  *
33  * (10^m-1)/9*x%k == c
34  * (10^m-1)*x/9%k == c
35  *  ***由于 (10^m-1)*x % 9 == 0;
36  * *** ----> (10^m-1)*x % (9*k) == 9*c;
37  *          ((10^m % 9*k) - 1 % 9*k) * x % (9*k)    mod(9*k)
38  * */
时间: 2024-08-06 03:44:35

hdu 5690(同余定理找循环节 / 快速幂)的相关文章

2016&quot;百度之星&quot; - 初赛(Astar Round2A)1001 All X(HDU5690)——找循环节|快速幂

一个由m个数字x组成的新数字,问其能否mod k等于c. 先提供第一种思路,找循环节.因为每次多一位数都是进行(t*10+x)mod k(这里是同余模的体现),因为x,k都确定,只要t再一样得到的答案一定一样.所以在一步一步中进行时一旦出现了一个之前出现过的数字,那么很显然后面就要开始进行循环了.找出这个循环节,然后把m放到这个循环节里头就行(这里的说法有问题,见下文的第二点). 但是这里有两个要注意的地方,第一是只有当前出现的数一样才能保证下一个出现的数一样,而并不代表着,当前的数一样,得到它

hdu 4506(数学,循环节+快速幂)

小明系列故事——师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 5427    Accepted Submission(s): 1461 Problem Description 小明自从告别了ACM/ICPC之后,就开始潜心研究数学问题了,一则可以为接下来的考研做准备,再者可以借此机会帮助一些同学,尤其是漂亮的师妹.这 不,班

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

(hdu 6030) Happy Necklace 找规律+矩阵快速幂

题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6030 Problem Description Little Q wants to buy a necklace for his girlfriend. Necklaces are single strings composed of multiple red and blue beads. Little Q desperately wants to impress his girlfriend,

HDU 5171 GTY&#39;s birthday gift(矩阵快速幂 )

HDU 5171 GTY's birthday gift ( 矩阵快速幂裸题目 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 3 #define MOD 10000007 #define clr( a, b ) memset( a, b, sizeof(a) ) typedef long long LL; struct M

HDU 4965 Fast Matrix Caculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 )

HDU 4965 Fast Matrix Calculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 1001 #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 6 typedef long lo

Hdu 5451 Best Solver (2015 ACM/ICPC Asia Regional Shenyang Online) 暴力找循环节 + 递推

题目链接: Hdu  5451  Best Solver 题目描述: 对于,给出x和mod,求y向下取整后取余mod的值为多少? 解题思路: x的取值为[1, 232],看到这个指数,我的心情是异常崩溃的.(吐血......) 可是仔细观察,它指数大,可是mod小啊,它吓人,可是可以暴力搞啊!! 这个题目一个难点就是要向下取整求余,详解见传送门,本题是向下取整,也就是向上取整加一. 还有就是指数太大,要找到循环节,其实由于mod小,循环节并没有太大,暴力跑就ok啦!  此刻内心是崩溃的 1 #i

特征根法求通项+广义Fibonacci数列找循环节 - HDU 5451 Best Solver

Best Solver Problem's Link Mean: 给出x和M,求:(5+2√6)^(1+2x)的值.x<2^32,M<=46337. analyse: 这题需要用到高中的数学知识点:特征根法求递推数列通项公式. 方法是这样的: 对于这题的解法: 记λ1=5+2√6,λ2=5-2√6,则λ1λ2=1,λ1+λ2=10 根据韦达定理可以推导出:λ1,λ2的特征方程为 x^2-10x+1=0 再使用该特征方程反向推导出递推公式为:a[n]=10*a[n-1]-a[n-2] 再由特征根

HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)

传送门:HDU 5895 Mathematician QSC 这是一篇很好的题解,我想讲的他基本都讲了http://blog.csdn.net/queuelovestack/article/details/52577212 [分析]一开始想简单了,对于a^x mod p这种形式的直接用欧拉定理的数论定理降幂了 结果可想而知,肯定错,因为题目并没有保证gcd(x,s+1)=1,而欧拉定理的数论定理是明确规定的 所以得另谋出路 那么网上提供了一种指数循环节降幂的方法 具体证明可以自行从网上找一找 有