hdu 1757 (矩阵快速幂) 一个简单的问题 一个简单的开始
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757
题意不难理解,当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);
所求的是f(x)取m的模,而x,m,a[0]至a[9]都是输入项
初拿到这道题,最开始想的一般是暴力枚举,通过for循环求出f(x)然后再取模,但是有两个问题,首先f(x)可能特别大,其次是枚举超时。
所以,想到可以用到通过构造矩阵快速幂的方法。
稍微有点线性代数基础的人(比如本人)都知道可以构造一个10*10的矩阵
(10有点大,这里以3*3的代替,题意还是不变)
0 0 a0 0 0 a0 0 0 a0
(f0,f1,f2)* 1 0 a1 --->(f1,f2,f3) 然后(f0,f1,f2)* 1 0 a1 * 1 0 a1 --->(f2,f3,f4)
0 1 a2 0 1 a2 0 1 a2
0 0 a0 0 0 a0
最后一直到f(x) (f0,f1,f2)* 1 0 a1* 1 0 a1*******--->(fx-2,fx-1,fx)
0 1 a2 0 1 a2
10*10的矩阵也基本很这个一样,然后光有矩阵并没有太大的卵用,还得用快速幂来取模,只不过换成了矩阵而已。
先开两个二维数组把矩阵给存起来(对,开两个存一模一样的矩阵,如果一下子没有反应过来为什么的等你写到这里的时候就知道为什么了)
然后第三个数组存相乘过程中的结果。(如果快速幂不会的请百度)
最后的用已知的f(i)数组的前十项分别乘以最终矩阵的最后一列的和就是最终结果
(PS:加减乘法的取模可以分步,而除法不行)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long jz1[][],jz2[][],jz3[][],i,j,k;
long long a[],m;
long long lsy(long long n)
{
long long sum=;
for (i=;i<=;i++){ //创建矩阵
for (j=;j<=;j++){
if (j!=){
if (i-j==)
{
jz1[i][j]=;
jz2[i][j]=;
}
else
{
jz1[i][j]=;
jz2[i][j]=;
}
}
else
{
jz1[i][]=a[-i];
jz2[i][]=a[-i];
}
}
}
n-=;
while (n!=) //快速幂取模
{
if (n&)
{
memset(jz3,,sizeof(jz3));
for (i=;i<=;i++){
for (j=;j<=;j++){
for (k=;k<=;k++){
jz3[i][j]+=jz1[i][k]*jz2[k][j]%m;
}
}
}
memcpy(jz2,jz3,sizeof(jz3));
}
memset(jz3,,sizeof(jz3));
for (i=;i<=;i++){
for (j=;j<=;j++){
for (k=;k<=;k++){
jz3[i][j]+=jz1[i][k]*jz1[k][j]%m;
}
}
}
memcpy(jz1,jz3,sizeof(jz3));
n>>=; //不要忘了
}
for (i=;i<;i++) //求出f(x)
sum=(((i%m)*jz2[i][])%m+sum)%m;
return sum;
}
int main()
{
long long n;
while (~scanf("%I64d %I64d",&n,&m))
{
if (n==&&m==) break;
for (i=;i<=;i++)
scanf("%l64d",&a[i]);
if (n>=)
printf("%I64d\n",lsy(n));
else
printf("%I64d\n",n%m);
}
return ;
}
hdu 1757 (矩阵快速幂) 一个简单的问题 一个简单的开始的更多相关文章
- hdu 1757 矩阵快速幂 **
一看正确率这么高,以为是水题可以爽一发,结果是没怎么用过的矩阵快速幂,233 题解链接:点我 #include<iostream> #include<cstring> ; us ...
- HDU 1757 矩阵快速幂加速递推
题意: 已知: 当x<10时:f(x)=x 否则:f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + --+ a9 * f(x-10); 求:f(x ...
- HDU 4471 矩阵快速幂 Homework
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4471 解题思路,矩阵快速幂····特殊点特殊处理····· 令h为计算某个数最多须知前h个数,于是写 ...
- HDU - 1575——矩阵快速幂问题
HDU - 1575 题目: A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input数据的第一行是一个T,表示有T组数据. 每组数据的第一行有n( ...
- HDU 3802 矩阵快速幂 化简递推式子 加一点点二次剩余知识
求$G(a,b,n,p) = (a^{\frac {p-1}{2}}+1)(b^{\frac{p-1}{2}}+1)[(\sqrt{a} + \sqrt{b})^{2F_n} + (\sqrt{a} ...
- HDU 2855 (矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2855 题目大意:求$S(n)=\sum_{k=0}^{n}C_{n}^{k}Fibonacci(k)$ ...
- HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂
装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1 ...
- 随手练——HDU 5015 矩阵快速幂
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5015 看到这个限时,我就知道这题不简单~~矩阵快速幂,找递推关系 我们假设第一列为: 23 a1 a2 ...
- hdu 1597(矩阵快速幂)
1597: 薛XX后代的IQ Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 228 Solved: 55[Submit][Status][Web Bo ...
随机推荐
- Android Monkey: “No activities found to run, monkey aborted”错误原因
用monkey测试app时,输入命令adb shell monkey -p com.example.test -v -500 发现报错, 错误输入: :Monkey: seed=13 count=5 ...
- 吴裕雄 10-MySQL插入数据
语法以下为向MySQL数据表插入数据通用的 INSERT INTO SQL语法:INSERT INTO table_name ( field1, field2,...fieldN ) VALUES ( ...
- 学JS的心路历程Day26 - PixiJS -入坑
后来知道也可以透过canvas让网页动起来! 而PixiJS是使用WebGL在canvas上绘制内容与制作动态 且同时有下列特色: 支持多点触控 掩码与混合模式 可外加WebGL滤镜 多装置支持 等等 ...
- c 语言的复杂声明
简化的声明语法: dcl: optional *'s direct-dcl direct-dcl: name (dcl) direct-dcl() direct-dcl[optional size] ...
- akka之种子节点
AKKA提供的cluser功能能够很便捷的创建一个分布式应用,在使用cluster时需要配置seed nodes节点,这里对seed nodes节点做一下介绍. AKKA seed nodes 和普通 ...
- JS----事件2
一 事件对象(event):与特定事件相关且包含有关该事件详细信息的对象 通过事件可以触发event对象的元素,鼠标的位置及状态,按下的键等等event对象只在事件发生的过程中才有效非IE浏览器里的e ...
- bootstrap 参考文档
https://getbootstrap.com/docs/3.3/css/#sass-installation
- matlab 画二维图与三维图
二维图 ezplot('sin(x)');%默认范围 ezplot('sin(x)',[-4 4]);%自己设定范围 三维图 ezmesh('x*x+y*y');%默认范围
- 1.3.1、CDH 搭建Hadoop在安装之前(端口---Cloudera Manager和Cloudera Navigator使用的端口)
下图概述了Cloudera Manager,Cloudera Navigator和Cloudera Management Service角色使用的一些端口: Cloudera Manager和Clou ...
- linux shell 学习笔记01
1.命令历史记录history !$ :调用上一条命令的执行结果 !100 :运行history记录里的第100条命令 !ser :调用以ser开头的最后一次执行的命令 ctrl+r ...