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;
}
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;
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++ Custom Control控件向父窗体发送对应的消息
- C++中拷贝构造函数的应用详解