HDU 5690 All X

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
 

Input
第一行一个整数 T ,表示 T 组数据。
每组测试数据占一行,包含四个数字 x,m,k,c

1x9  

1m1010

0c<k10,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[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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值