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

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”。

Source

2016"百度之星" - 初赛(Astar Round2A)

解题思路:打表找循环节。

#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;
}

  

时间: 2024-10-11 03:52:22

HDU 5690——All X——————【快速幂 | 循环节】的相关文章

HDU 4291 A Short problem(矩阵快速幂+循环节)

题目链接": http://acm.hdu.edu.cn/showproblem.php?pid=4291 题意: g(0)=0,g(1)=1; g(n) = 3g(n - 1) + g(n - 2): 求g(g(g(n))) mod 109 + 7 分析: 首先我们得认识到,如果一层一层算是必定会超时的. 其次,取模运算是有循环节的. step1我们找出g(x)%1000000007的循环节 mod1 step2 设g(g(n)) = g(x) x=g(n) 对mod1 取模得到mod2. 剩

hdu 4291(矩阵快速幂 + 循环节)

题意:求s s = g(g(g(n))) mod 1000000007 其中g(n) g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0 题解:普通的矩阵快速幂会超时,看到别人的题解是需要计算循环节得到小的MOD从而减小计算量.1000000007太大,需要计算更小的一个循环节,新技能get. #include <stdio.h> #include <string.h> struct Mat { long long g[3][3]; }ori

HDU——4291A Short problem(矩阵快速幂+循环节)

A Short problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2461    Accepted Submission(s): 864 Problem Description According to a research, VIM users tend to have shorter fingers, compared

【矩阵快速幂+循环节】HDU 5451 Best Solver

通道 题意:计算(5+26√)1+2^x. 思路:循环节是(p+1)*(p-1),然后就是裸的矩阵快速幂啦. 代码: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N = 2; int MOD; struct

[矩阵快速幂+循环节]hdu4291

题意: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where g(n) = 3g(n - 1) + g(n - 2) g(1) = 1 g(0) = 0 分析: 这个递推关系可以用矩阵快速幂来解决,但是这个题的问题是mod很大,会爆long long 并且超时的.那么这就需要一些特技了. 于是看到大家都用的循环节,但是网上对为什么要这么取循环节却都模糊或者答非所问,大概都不太晓得,知道可以A提就可

2016&quot;百度之星&quot; - 初赛(Astar Round2A)--HDU 5690 |数学转化+快速幂

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". 解: m个x组成的数可以表示为x*(1+10+10^2+...+10^m-1)=x*(10^m-1)/9; 即x*(10^m-1)/9%

acdream 1060 递推数 (矩阵快速幂+循环节)

链接:click here~~ 题意: 递推数 Problem Description 已知A(0) = 0 , A(1) = 1 , A(n) = 3 * A(n-1) + A(n-2) (n ≥ 2)    求 A(A(A(A(N)))) Mod (1e9 + 7) Input 第一行一个整数 T (T ≤ 10000) 代表数据组数 每组数据占一行,一个整数 n (1 ≤ n ≤ 1e12) Output 对于每组测试数据输出一个整数. Sample Input 4 1 23574 278

hdu 5451 Best Solver(矩阵快速幂+循环节)

题意: 已知,给你整数x,和一个素数M,求[y]%M 思路: 设 (5+2√6)n=Xn+Yn*√6 Xn+Yn*√6 =(Xn-1+Yn-1*√6)*(5+2√6) => 5*Xn-1 + 12*Yn-1 + (2*Xn-1 + 5*Yn-1 )*√6 Xn =  5*Xn-1 + 12*Yn-1: Yn =  2*Xn-1 + 5*Yn-1: 然而√6还是一个大问题,解决办法: (5 - 2√6)n = Xn - Yn*√6 (5+2√6)n=Xn+Yn*√6 + Xn - Yn*√6 -

HDU 4291 A Short problem (2012成都网络赛,矩阵快速幂+循环节)

链接: click here~~ 题意: According to a research, VIM users tend to have shorter fingers, compared with Emacs users. Hence they prefer problems short, too. Here is a short one: Given n (1 <= n <= 1018), You should solve for g(g(g(n))) mod 109 + 7 where