快速幂、矩阵快速幂

乘法快速幂:

P1226 【模板】快速幂 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;public class Code01_QuickPower {public static long a, b, p;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));in.nextToken();a = (int) in.nval;in.nextToken();b = (int) in.nval;in.nextToken();p = (int) in.nval;out.println(a + "^" + b + " mod " + p + "=" + power());out.flush();out.close();br.close();}public static int power() {long ans = 1;while (b > 0) {if ((b & 1) == 1) {ans = (ans * a) % p;}a = (a * a) % p;b >>= 1;}return (int) ans;}}

对于a^b,把b看作二进制形式,让a从1次方开始,只要b的二进制形式某位上有1,就把此时的a加入(a不断的自乘的幂就对应二进制的每一位)。时间复杂度为logb

 矩阵的乘法:

vector<vector<int>> f(vector<vector<int>>& a, vector<vector<int>>& b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<int>>ans(n, vector<int>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] += a[i][h] * b[h][j];}}}return ans;
}

 矩阵快速幂:前提矩阵必须是方阵。大体流程和乘法的快速幂是一样的

vector<vector<int>> power(vector<vector<int>>& a, int p) {int n = a.size();vector<vector<int>>ans(n,vector<int>(n,0));for (int i = 0; i < n; i++) {//设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans=f(ans, a);a = f(a, a);p>>=1;}return ans;
}

利用矩阵快速幂解决的问题:优化dp问题

1.固定关系的1维k阶表达式(即某一项只有一个维度,是由前好几项推出的,且递推关系式是固定的),时间复杂度为O(logn*k^3)。关系矩阵的第1列由递推关系确定,剩下的项待定系数求出

2.固定关系的k维1阶表达式(即某一项中有好几个维度,但只需要前一项就可以求出)

1维k阶:

509. 斐波那契数 - 力扣(LeetCode)

class Solution {
public:vector<vector<int>> f(vector<vector<int>>& a, vector<vector<int>>& b) {//矩阵乘法int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<int>> ans(n, vector<int>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] += a[i][h] * b[h][j];}}}return ans;}vector<vector<int>> power(vector<vector<int>>& a, int p) {//矩阵快速幂int n = a.size();vector<vector<int>> ans(n, vector<int>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int fib(int n) {if (n == 0)return 0;if (n == 1)return 1;vector<vector<int>> start = {{1, 0}};//初始数据逆序排列vector<vector<int>> base = {{1, 1}, {1, 0}};//关系矩阵vector<vector<int>> rem = power(base, n - 1);vector<vector<int>> ans = f(start, rem);return ans[0][0];}
};

注意:1.初始数据构成的矩阵的排列方式   2.关系矩阵的构成    3.最终得到的矩阵中答案的位置

 70. 爬楼梯 - 力扣(LeetCode)

class Solution {
public:vector<vector<long>> f(vector<vector<long>> a, vector<vector<long>> b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<long>> ans(n, vector<long>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] += a[i][h] * b[h][j];}}}return ans;}vector<vector<long>> power(vector<vector<long>> a, int p) {int n = a.size();vector<vector<long>> ans(n, vector<long>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int climbStairs(int n) {if (n==0||n == 1)return 1;vector<vector<long>> start = {{1, 1}};vector<vector<long>> base = {{1, 1}, {1, 0}};vector<vector<long>> rem = power(base, n - 1);vector<vector<long>> ans = f(start, rem);return ans[0][0];}
};

 和斐波那契数列一样,只是0项为1

 1137. 第 N 个泰波那契数 - 力扣(LeetCode)

class Solution {
public:vector<vector<long>> f(vector<vector<long>> a, vector<vector<long>> b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<long>> ans(n, vector<long>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] += a[i][h] * b[h][j];}}}return ans;}vector<vector<long>> power(vector<vector<long>> a, int p) {int n = a.size();vector<vector<long>> ans(n, vector<long>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int tribonacci(int n) {if (n == 0)return 0;if (n == 1 || n == 2)return 1;vector<vector<long>> start = {{1, 1, 0}};vector<vector<long>> base = {{1, 1, 0}, {1, 0, 1}, {1, 0, 0}};vector<vector<long>> rem = power(base, n - 2);vector<vector<long>> ans = f(start, rem);return ans[0][0];}
};

此时的递推关系为3维,所以关系矩阵为3维矩阵

790. 多米诺和托米诺平铺 - 力扣(LeetCode)

// f(1) = 1// f(2) = 2// f(3) = 5// f(4) = 11// f(n) = 2 * f(n-1) + f(n-3)// 打表或者公式化简都可以发现规律,这里推荐打表找规律public static void main(String[] args) {for (int i = 1; i <= 9; i++) {System.out.println("铺满 2 * " + i + " 的区域方法数 : " + f(i, 0));}}// 暴力方法// 为了找规律// 如果h==0,返回2*n的区域铺满的方法数// 如果h==1,返回1 + 2*n的区域铺满的方法数public static int f(int n, int h) {if (n == 0) {return h == 0 ? 1 : 0;}if (n == 1) {return 1;}if (h == 1) {return f(n - 1, 0) + f(n - 1, 1);} else {return f(n - 1, 0) + f(n - 2, 0) + 2 * f(n - 2, 1);}}

 此题先通过打表找规律,观察推出递推关系式

class Solution {
public:static const int mod=1000000007;vector<vector<long>> f(vector<vector<long>>& a, vector<vector<long>>& b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<long>> ans(n, vector<long>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] = (ans[i][j]+a[i][h] * b[h][j])%mod;}}}return ans;}vector<vector<long>> power(vector<vector<long>>& a, int p) {int n = a.size();vector<vector<long>> ans(n, vector<long>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int numTilings(int m) {int n=m-1;if(n==0)return 1;if(n==1)return 2;if(n==2) return 5;vector<vector<long>>start={{5,2,1}};vector<vector<long>>base={{2,1,0},{0,0,1},{1,0,0}};vector<vector<long>>rem=power(base,n-2);vector<vector<long>>ans=f(start,rem);return (int)ans[0][0];}
};

注:对于方阵幂的次数,从0项开始,求第n项,且递推表达式维度为k维,则幂的次数为(n-(k-1))

k维1阶:

1220. 统计元音字母序列的数目 - 力扣(LeetCode)

class Solution {
public:static const int mod = 1000000007;vector<vector<long>> f(vector<vector<long>> a, vector<vector<long>> b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<long>> ans(n, vector<long>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] = (ans[i][j] + a[i][h] * b[h][j]) % mod;}}}return ans;}vector<vector<long>> power(vector<vector<long>> a, int p) {int n = a.size();vector<vector<long>> ans(n, vector<long>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int countVowelPermutation(int n) {vector<vector<long>> start = {{1, 1, 1, 1, 1}};vector<vector<long>> base = {{0, 1, 0, 0, 0},{1, 0, 1, 0, 0},{1, 1, 0, 1, 1},{0, 0, 1, 0, 1},{1, 0, 0, 0, 0}};int sum = 0;vector<vector<long>> rem = power(base, n - 1);vector<vector<long>> ans = f(start, rem);for (auto i : ans[0])sum = (sum + i) % mod;return sum;}
};

dp[i][k]表示长度为i中以k字符结尾的合法字符串有多少种,最后将5种不同的字符累加求和即可。通过递推关系可知,每项至于前一项有关,且每一项的维度有多个,所以此时可以根据递推关系写出关系表达式,然后按照k阶1维的方法求出答案矩阵

  552. 学生出勤记录 II - 力扣(LeetCode)

class Solution {
public:static const int mod = 1000000007;vector<vector<long>> f(vector<vector<long>> a, vector<vector<long>> b) {int n = a.size();int m = b[0].size();int k = a[0].size();vector<vector<long>> ans(n, vector<long>(m, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int h = 0; h < k; h++) {ans[i][j] = (ans[i][j] + a[i][h] * b[h][j]) % mod;}}}return ans;}vector<vector<long>> power(vector<vector<long>> a, int p) {int n = a.size();vector<vector<long>> ans(n, vector<long>(n, 0));for (int i = 0; i < n; i++) { // 设为单位阵ans[i][i] = 1;}while (p > 0) {if (p & 1)ans = f(ans, a);a = f(a, a);p >>= 1;}return ans;}int checkRecord(int n) {vector<vector<long>> start = {{1, 1, 0, 1, 0, 0}};vector<vector<long>> base = {{1, 1, 0, 1, 0, 0}, {1, 0, 1, 1, 0, 0},{1, 0, 0, 1, 0, 0}, {0, 0, 0, 1, 1, 0},{0, 0, 0, 1, 0, 1}, {0, 0, 0, 1, 0, 0}};vector<vector<long>> rem = power(base, n - 1);int sum = 0;vector<vector<long>> ans = f(start, rem);for (auto i : ans[0])sum = (sum + i) % mod;return sum;}
};

 定义dp[i][j][k]表示长度为i且缺勤次数为j且最后有k天连续迟到的种类数,把各种情况压缩为二维,分别求出各种情况的递推关系。最后累加即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/397341.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C#】一个项目移动了位置,或者换到其他电脑上,编译报错 Files 的值“IGEF,解决方法

文章目录 1 问题分析2 本文解决方法 一个项目可以正常运行编译的项目&#xff0c;所有路径均为相对路径。 移动了位置&#xff0c;或者换到其他电脑上&#xff0c;编译报错 Files 的值“IGEF&#xff0c; 1 问题分析 这个错误信息表明在处理文件时&#xff0c;Files 的值出…

(限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!

目录 haproxy七层代理详解一、负载均衡1.1 什么是负载均衡1.2 为什么使用负载均衡1.3 负载均衡类型1.3.1 硬件负载1.3.2 四层负载1.3.3 七层负载1.3.4 四层与七层的区别 二、haproxy介绍2.1 haproxy简介2.2 haproxy特性 三、haproxy详细部署3.1 实验所用的环境3.2 软件安装3.3 …

C语言 | Leetcode C语言题解之第330题按要求补齐数组

题目&#xff1a; 题解&#xff1a; int minPatches(int* nums, int numsSize, int n) {int patches 0;long long x 1;int index 0;while (x < n) {if (index < numsSize && nums[index] < x) {x nums[index];index;} else {x << 1;patches;}}retu…

【HarmonyOS NEXT星河版开发学习】小型测试案例06-小红书卡片

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;暂未发布&#xff09; 前言 在鸿蒙&#xff08;HarmonyOS&#xff09;开发中&#xff0c;自适应伸缩是指应用程序能够根据不同设备的屏幕尺寸、分辨率和形态&…

气象大数据案例项目(求各气象站的平均气温)

气象大数据案例项目&#xff08;求各气象站的平均气温&#xff09; 一、项目需求二、数据格式三、项目开发3.1 在windows 进行开发3.2 运行结果3.3 对项目打包 一、项目需求 现在有一份来自美国国家海洋和大气管理局的数据集&#xff0c;里面包含近30年每个气象站、每小时的天…

WSL2 最新最全帮助小白一步步详细安装教程

文章目录 一、前言1.1、什么是 WSL &#xff1f;1.2、WSL2 相比传统虚拟机的优势1.3、微软官方 二、安装步骤*2.1、启用 WSL 功能2.2、重启电脑2.3、dos命令自动安装 (一行命令搞定&#xff0c;非常方便)2.3.1、通过 cmd 打开 dos 命令行 或者 WIN键 R&#xff1a;2.3.2、输入…

探案录 | 在线打补丁,运维更轻松

清晨&#xff0c;曙光温柔地洒落在福尔摩斯K那标志性的书房内&#xff0c;福尔摩斯K坐在他那张熟悉的扶手椅上&#xff0c;眼神锐利如鹰&#xff0c;正沉浸在思考的海洋中。门突然被推开&#xff0c;华生K带着一丝急切步入室内。 “福尔摩斯K&#xff0c;这次案件非同小可&…

如何在线观看汤姆克鲁斯、比莉艾利什、红辣椒乐队、HER等明星的奥运闭幕式

2024 年巴黎奥运会将以一系列众星云集的表演者为结尾&#xff0c;他们将帮助将奥运会移交给洛杉矶——以下是在线直播盛大决赛的时间和地点。 经过两周多令人惊叹的田径运动、激烈的比赛和表情包活动后&#xff0c;2024 年巴黎奥运会即将落下帷幕。 奥运会闭幕式将于 8 月 12 …

【C++】 特殊类设计:从构思到实现,引领设计新潮流

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;C从入门到精通 目录 &#x1f680; 前言 一&#xff1a; &#x1f525; 不能被拷贝的类 二&#xff1a; &#x1f525; 只能在堆上创建对象的类 三&#xff1a; &#x1f525; 只能在栈上创建对象的…

uniapp使用echarts在H5上显示报错问题的解决方法

前言 在做uniapp vue3开发的echarts图表的时候&#xff0c;发现在浏览器上面正常运行&#xff0c;但在微信开发者工具上显示报错了&#xff0c;报错如下 原因&#xff1a;在微信小程序中&#xff0c;使用document.getElementById会报错&#xff0c;因为小程序的运行环境是基于…

目前最强的文生图模型?!FLUX完全解读!附体验地址

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

css rem之2024

话题开始前 我们都知道1rem是等于html fontSize标签的字体大小的&#xff0c;我们主要用来做移动端网页设计稿等比例在手机上面的显示。 看到的问题 这个html fontsize的大小是通过js动态计算的&#xff0c;而这个js的运行时晚于html渲染的&#xff0c;所以会导致一个问题&am…

python网络爬虫使用代理

Python网络爬虫使用代理的实用指南 在网络爬虫的开发过程中&#xff0c;使用代理是一个非常重要的环节。代理不仅可以帮助爬虫绕过反爬虫机制&#xff0c;还能保护开发者的隐私。本文将介绍如何在Python中使用代理进行网络爬虫&#xff0c;包括基本的设置和示例代码。 1. 代理…

WordPress多用途电子商务博客新闻主题betheme 21.5.6版本

简介&#xff1a; WordPress多用途电子商务博客新闻主题betheme 21.5.6版本 自带500多套模板 BeTheme第一次发布于2014年5月21日&#xff0c;自那时以来&#xff0c;已有数以百万计的人下载了BeTheme&#xff0c;其评分为4.8。 这个主题是WooCommerce支持的&#xff0c;在此…

Git代码管理规范

1. 简介 git 分支分为集成分支、功能分支和修复分支&#xff0c;分别命名为 develop、feature 和 hotfix&#xff0c;均为单数。不可使用 features、future、hotfixes、hotfixs 等错误名称。 master&#xff08;主分支&#xff0c;永远是可用的稳定版本&#xff0c;不能直接在…

mybatis xml 动态sql相关语法

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace"com.xiaKangan.mapper.EmpMapper&qu…

JavaScript 文档元素获取

目录 通过id获取文档元素 任务描述 相关知识 什么是DOM 文档元素 节点树 通过id获取文档元素 编程要求 通过类名获取文档元素 任务描述 相关知识 通过类名获取文档元素 编程要求 通过标签名获取文档元素 任务描述 相关知识 通过标签的名字获取文档元素 获取标…

android13 关闭selinux 临时关闭或者永久关闭

总纲 android13 rom 开发总纲说明 目录 1.前言 2.情况分析 2.1 临时关闭 2.2 永久关闭 3.修改方法 3.1 临时修改 3.2 永久关闭 4.编译测试 5.彩蛋 1.前言 在Android操作系统中,SELinux(Security-Enhanced Linux)是一种安全模块,用于提供强制访问控制(MAC)安全…

IDEA自定义注释模版

1.类&#xff08;接口/枚举等同理&#xff09; 2.方法模版 先自定义一个模版组&#xff0c;然后在里面添加模版名&#xff0c;触发快捷键&#xff08;Tab/Enter&#xff09;&#xff0c;模版描述&#xff0c;哪些语言中应用 模版中的自定义参数params和returns可以自动展开参数…

Linux学习记录(五)-------三类读写函数

文章目录 三种读写函数1.行缓存2.无缓存3.全缓存4.fgets和fputs5.gets和puts 三种读写函数 1.行缓存 遇到新行&#xff08;\n&#xff09;,或者写满缓存时&#xff0c;即调用系统函数 读&#xff1a;fgets,gets,printf,fprintf,sprintf写&#xff1a;fputs,puts,scanf 2.无缓…