hdu5690百度之星All X(矩阵快速幂)

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”,代表四个数字,是否能够满足题目中给的公式。

/*
 这道题拿来肯定知道如果暴力过去10的10次方肯定超时,那么肯定会超时的,现在问题就变成了如何求 m个k的大小
f=f*10+k
 这样就可以推导出来公式为[k,1]* [10 0]的m-1次方
				[x  1]
*/
#include <cstdio>
#include <iostream>

using namespace std;
typedef __int64 ll;
ll m;
int k,mod,c;

struct matrix
{
    int m[2][2];
}ans, base;

matrix multi(matrix a, matrix b)
{
    matrix tmp;
    for(int i = 0; i < 2; ++i)
    {
        for(int j = 0; j < 2; ++j)
        {
            tmp.m[i][j] = 0;
            for(int k = 0; k < 2; ++k)
                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
        }
    }
    return tmp;
}
int fast_mod(ll n)  // 求矩阵 base 的  n 次幂 
{
    base.m[0][0] = 10;
	base.m[0][1] = 0;
	base.m[1][0] = k;
    base.m[1][1] = 1;
    ans.m[0][0] = ans.m[1][1] = 1;  // ans 初始化为单位矩阵 
    ans.m[0][1] = ans.m[1][0] = 0;
    while(n)
    {
        if(n & 1)  //实现 ans *= t; 其中要先把 ans赋值给 tmp,然后用 ans = tmp * t 
        {
            ans = multi(ans, base);
        }
        base = multi(base, base);
        n >>= 1;
    }
    return ans.m[0][0]*k+ans.m[1][0];
}

int main()
{
	int t,cas=1;
	scanf("%d",&t);
	while(t--)
	{
		printf("Case #%d:\n",cas);
		cas++;
		scanf("%d%I64d%d%d",&k,&m,&mod,&c);
		ll ans=(fast_mod(m-1)+mod)%mod;
		if(ans==c)
			printf("Yes\n");
		else
			printf("No\n");
	}
    return 0;
}


你可能感兴趣的:(HDU)