您的位置:首页 > 编程语言 > C语言/C++

HDU 4979 A simple math problem.

2015-07-20 15:36 691 查看
A Simple Math Problem
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Lele now is thinking about a simple function f(x). 

If x < 10 f(x) = x. 

If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10); 

And ai(0<=i<=9) can only be 0 or 1 . 

Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m. 

 

Input

The problem contains mutiple test cases.Please process to the end of file. 

In each case, there will be two lines. 

In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 ) 

In the second line , there are ten integers represent a0 ~ a9. 

 

Output

For each case, output f(k) % m in one line.
 

Sample Input

10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0

 

Sample Output

45
104

 

题意

一个分段函数f(x)。

当 x < 10 时,f(x) = x。

当 x >= 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)。

并且 ai(0<=i<=9) 只能是 0 或 1。

现在给出 a0 ~ a9 ,k 和 m ,输出f(k) % m( k < 2 * 10^9 , m < 10^5 )。

分析

看 k 的范围知道 k 很大,直接跑 o(n) 的循环肯定会 T 掉,所以想到用矩阵来加速,构造的矩阵A为10*10矩阵,如下

 0   1   0   0   0   0   0   0   0   0

 0   0   1   0   0   0   0   0   0   0

 0   0   0   1   0   0   0   0   0   0

 0   0   0   0   1   0   0   0   0   0

 0   0   0   0   0   1   0   0   0   0

 0   0   0   0   0   0   1   0   0   0

 0   0   0   0   0   0   0   1   0   0

 0   0   0   0   0   0   0   0   1   0

 0   0   0   0   0   0   0   0   0   1

a9 a8 a7 a6 a5 a4 a3 a2 a1 a0

所求问题可转化为求由f(0),f(1),...,f(9)构成的列矩阵 F 与 A 的乘法,只需乘 k-9 次即可。

10 * 10 的矩阵看着是真头疼,Orz......

AC代码如下

#include<cstdio>
#include<cstring>
#define N 10
using namespace std;

int k,m;
struct S
{
int m

;
};

S matrix_multiplication(S a,S b)
{
S c;
memset(c.m,0,sizeof(c.m));
for(int i = 0 ; i < N ; i++)
for(int j = 0 ; j < N ; j++)
{
for(int k = 0 ; k < N ; k++)
c.m[i][j] += (a.m[i][k] * b.m[k][j]) % m;
c.m[i][j] %= m;
}
return c;
}

S quick_power(S a,int x)
{
if(x == 1) return a;
else if(x & 1) return matrix_multiplication(quick_power(a,x-1),a);
else
{
S c = quick_power(a,x/2);
return matrix_multiplication(c,c);
}
}

int main()
{
S a;
while(~scanf("%d%d",&k,&m))
{
for(int i = N-1 ; i >= 0; i--)
scanf("%d",&a.m[9][i]);
if(k < 10)
{
printf("%d\n",k % m);
continue;
}
for(int i = 0 ; i < N-1 ; i++)
for(int j = 0 ; j < N ; j++)
{
if(j == i + 1) a.m[i][j] = 1;
else a.m[i][j] = 0;
}
S res = quick_power(a,k-9);
int ans = 0;
for(int i = 0 ; i < N ; i++)
ans += (res.m[9][i] * i) % m;
printf("%d\n",ans%m);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息