[SPOJ SPP] Recursive Sequence (Version II) 矩阵加速

2023-12-07 07:18

本文主要是介绍[SPOJ SPP] Recursive Sequence (Version II) 矩阵加速,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果不求和这道题就变成了UVA10870(以前发过,不多说) 加入求和后就需要更改之前的矩阵了

首先保存有关项是必要的 这关系到递推的进行 但是需要额外加入一项 那就是前N项和 这个何又上一次的前N项和 + 前面存下来的相关项乘系数相加得到 例如Fib数列 构造如下矩阵

1            1             2

第一项   第二项    和

那么得到他的计算矩阵

0            1           1

1            1           1

0            0           1

继承相关项     计算新项          计算新的和

得到这样的矩阵后便可解决此题了 需要注意的是我之前写的乘法是利用函数返回答案 这样导致了这道题的超时 所以我改为了直接在函数内部赋值

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXN 15
#define MAXM 15
typedef long long LL;
struct Matrix{  int n, m;  LL A[MAXN+10][MAXN+10];  
};
LL a[MAXN], f[MAXN];
int d;
LL p;
const LL INF = 10000000000LL;
Matrix A, B, E, Z;
void init(Matrix &X)
{X.n = X.m = 0;memset(X.A, 0, sizeof(X.A));
}
void Get_E()
{E.n = E.m = MAXN;for(int i = 0; i < E.n; i++) E.A[i][i] = 1;
}
Matrix add(Matrix AA, Matrix BB)
{Matrix D; D = AA;for(int i = 0; i < AA.n; i++)for(int j = 0; j < AA.m; j++){D.A[i][j] += BB.A[i][j];D.A[i][j] %= p;}return D;
}
void mul(Matrix AA, Matrix BB, Matrix &Ans)
{Matrix D;init(D);Ans.n = D.n = AA.n;Ans.m = D.m = BB.m;for(int i = 0; i < AA.n; i++)for(int j = 0; j < BB.n; j++)for(int k = 0; k < BB.m; k++){D.A[i][k] += (AA.A[i][j] * BB.A[j][k]) % p;D.A[i][k] %= p;}memcpy(Ans.A, D.A, sizeof(D.A));
}
Matrix pow_mod(Matrix &A, LL k)
{Matrix ans = E, t = A;ans.n = A.n;ans.m = A.m;while(k){if(k & 1)mul(ans, t, ans);mul(t, t, t);k >>= 1;}return ans;
}
int main()
{ios::sync_with_stdio(false);Get_E();init(Z);int kase;cin >> kase;while(kase--)          // A 初始矩阵 B 构造的矩阵{LL st, ed;cin >> d;d++;init(A); init(B); for(int i = 0; i < d-1; i++) cin >> a[i];for(int i = 0; i < d-1; i++) cin >> f[i];for(int i = 0; i < (d-1-i-1); i++) swap(f[i], f[d-i-2]);cin >> st >> ed >> p;A.n = 1;A.m = d;Z.n = Z.m = E.n = E.m = B.n = B.m = d;LL FN = 0, FM = 0;for(int i = 0; i < d-1; i++)B.A[i][d-2] = B.A[i][d-1] = f[i];for(int i = 1; i < d-1; i++) B.A[i][i-1] = 1;B.A[d-1][d-1] = 1;for(int i = 0; i < d-1; i++){A.A[0][i] = a[i];A.A[0][d-1] = (A.A[0][d-1] + a[i]) % p;}if(ed <= d){for(int i = st; i <= ed; i++) FM = (FM + a[i]) % p;cout << FM << '\n';continue;}if(st >= d){Matrix Tmp = pow_mod(B, st-d);mul(A, Tmp, Tmp);FN = Tmp.A[0][d-1];Tmp = pow_mod(B, ed-d+1);mul(A, Tmp, Tmp);FM = Tmp.A[0][d-1];cout << (FM - FN + p) % p << '\n';continue;}else{for(int i = 0; i < st-1; i++) FM -= a[i];Matrix Tmp = pow_mod(B, ed-d+1);mul(A, Tmp, Tmp);FM += Tmp.A[0][d-1];cout << FM % p << '\n';continue;}}
}


这篇关于[SPOJ SPP] Recursive Sequence (Version II) 矩阵加速的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464973

相关文章

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

学习记录:js算法(二十八):删除排序链表中的重复元素、删除排序链表中的重复元素II

文章目录 删除排序链表中的重复元素我的思路解法一:循环解法二:递归 网上思路 删除排序链表中的重复元素 II我的思路网上思路 总结 删除排序链表中的重复元素 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 图一 图二 示例 1:(图一)输入:head = [1,1,2]输出:[1,2]示例 2:(图

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1:安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件,完成后可能需要重启 Jenkins。 步骤 2:配置版本号生成 打开项目配置页面。在下方找到 “Build Env

线性代数|机器学习-P35距离矩阵和普鲁克问题

文章目录 1. 距离矩阵2. 正交普鲁克问题3. 实例说明 1. 距离矩阵 假设有三个点 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​,三个点距离如下: ∣ ∣ x 1 − x 2 ∣ ∣ 2 = 1 , ∣ ∣ x 2 − x 3 ∣ ∣ 2 = 1 , ∣ ∣ x 1 − x 3 ∣ ∣ 2 = 6 \begin{equation} ||x