杭电ACM-LCY算法进阶培训班-专题训练(矩阵快速幂)【模板】

传送门

  • 杭电ACM-LCY算法进阶培训班-专题训练(矩阵快速幂)【模板】
    • 矩阵快速幂模板
    • Count
      • Problem Description
      • Input
      • Output
      • Sample Input
      • Sample Output
      • Source
      • 思路
    • Sum of Tribonacci Numbers
      • Problem Description
      • Input
      • Output
      • Sample Input
      • Sample Output
      • Author
      • Source
      • 思路
    • Another kind of FibonacciProblem Description
      • Input
      • Output
      • Sample Input
      • Sample Output
      • Author
      • Source
      • 思路
    • Kiki & Little Kiki 2
      • Problem Description
      • Input
      • Output
      • Sample Input
      • Sample Output
      • Source
      • 思路

矩阵快速幂模板

void mul(){int c[maxn];memset(c,0,sizeof(c));for(int j=0;j<len;j++)for(int k=0;k<len;k++)c[j]=(c[j]+a[j][k]*b[k])%mod;memcpy(b,c,sizeof(b));
}void mulSelf(){int c[maxn][maxn];memset(c,0,sizeof(c));for(int i=0;i<len;i++)for(int j=0;j<len;j++)for(int k=0;k<len;k++)c[i][j]=(c[i][j]+a[i][k]*a[k][j])%mod;memcpy(a,c,sizeof(c));
}int main(){for(;n;n>>=1){if(n&1) mul();mulSelf();}
}

Count

Problem Description

Farmer John有n头奶牛.
某天奶牛想要数一数有多少头奶牛,以一种特殊的方式:
第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.
现在Farmer John想知道,第n头奶牛的编号是多少,估计答案会很大,你只要输出答案对于123456789取模.

Input

第一行输入一个T,表示有T组样例
接下来T行,每行有一个正整数n,表示有n头奶牛 (n>=3)
其中,T= 1 0 4 10^4 104, n < = 1 0 18 n<=10^{18} n<=1018

Output

共T行,每行一个正整数表示所求的答案

Sample Input

5
3
6
9
12
15

Sample Output

31
700
7486
64651
527023

Source

“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛

思路

递推公式为: d p [ i ] = d p [ i − 1 ] + 2 d p [ i − 2 ] + n 3 dp[i]=dp[i-1]+2dp[i-2]+n^3 dp[i]=dp[i−1]+2dp[i−2]+n3。但是这种形式无法直接用矩阵快速幂来解。
因为: n 3 = ( n − 1 + 1 ) 3 = ∑ k = 0 3 C 3 k ( n − 1 ) k = 1 + 3 ( n − 1 ) + 3 ( n − 1 ) 2 + ( n − 1 ) 3 n^3=(n-1+1)^3=\sum_{k=0}^3C_3^k(n-1)^k=1+3(n-1)+3(n-1)^2+(n-1)^3 n3=(n−1+1)3=∑k=03​C3k​(n−1)k=1+3(n−1)+3(n−1)2+(n−1)3,可以构造下面的矩阵:
[ f n f n − 1 n 3 n 2 n 1 ] = [ 1 2 1 3 3 1 1 0 0 0 0 0 0 0 1 3 3 1 0 0 0 1 2 1 0 0 0 0 1 1 0 0 0 0 0 1 ] × [ f n − 1 f n − 2 ( n − 1 ) 3 ( n − 1 ) 2 n − 1 1 ] \begin{bmatrix} f_n\\ f_{n-1}\\ n^3\\ n^2\\ n\\ 1\\ \end{bmatrix}= \begin{bmatrix} 1&2&1&3&3&1\\ 1&0&0&0&0&0\\ 0&0&1&3&3&1\\ 0&0&0&1&2&1\\ 0&0&0&0&1&1\\ 0&0&0&0&0&1\\ \end{bmatrix}\times \begin{bmatrix} f_{n-1}\\ f_{n-2}\\ (n-1)^3\\ (n-1)^2\\ n-1\\ 1\\ \end{bmatrix} ⎣⎢⎢⎢⎢⎢⎢⎡​fn​fn−1​n3n2n1​⎦⎥⎥⎥⎥⎥⎥⎤​=⎣⎢⎢⎢⎢⎢⎢⎡​110000​200000​101000​303100​303210​101111​⎦⎥⎥⎥⎥⎥⎥⎤​×⎣⎢⎢⎢⎢⎢⎢⎡​fn−1​fn−2​(n−1)3(n−1)2n−11​⎦⎥⎥⎥⎥⎥⎥⎤​

#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int mod=123456789;
int bCP[6][6]={{1,2,1,3,3,1},{1,0,0,0,0,0},{0,0,1,3,3,1},{0,0,0,1,2,1},{0,0,0,0,1,1},{0,0,0,0,0,1}},b[6][6];
int aCP[6]={2,1,8,4,2,1},a[6];void mul(){int c[6];memset(c,0,sizeof(c));for(int j=0;j<6;j++)for(int k=0;k<6;k++)c[j]=(c[j]+a[k]*b[j][k])%mod;memcpy(a,c,sizeof(a));
}void mulSelf(){int c[6][6];memset(c,0,sizeof(c));for(int i=0;i<6;i++)for(int j=0;j<6;j++)for(int k=0;k<6;k++)c[i][j]=(c[i][j]+b[i][k]*b[k][j])%mod;memcpy(b,c,sizeof(b));
}void solve(){int n;memcpy(a,aCP,sizeof(a));memcpy(b,bCP,sizeof(b));cin>>n; n-=2;for(;n;n>>=1){if(n&1) mul();mulSelf();}cout<<a[0]<<"\n";
}signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int te;cin>>te;while(te--) solve();
}

Sum of Tribonacci Numbers

Problem Description

Everybody knows Fibonacci numbers, now we are talking about the Tribonacci numbers:
T[0] = T[1] = T[2] = 1;
T[n] = T[n - 1] + T[n - 2] + T[n - 3] (n >= 3)

Given a and b, you are asked to calculate the sum from the ath Fibonacci number to the bth Fibonacci number, mod 1,000,000,007, that is (T[a] + T[a + 1] + … + T[b]) % 1,000,000,007.

Input

There are multiple cases (no more than 100).

Each case contain two non-negative integers a b(a <= b and a, b < 1,000,000,000)

Output

For each case, output the sum % 1,000,000,007.

Sample Input

0 2
0 5

Sample Output

3
20

Author

hhanger@zju

Source

HDOJ 2009 Summer Exercise(5)

思路

设S[i]为数列T[i]的前缀和,那么易得 S [ i ] = S [ i − 1 ] + T [ i ] S[i]=S[i-1]+T[i] S[i]=S[i−1]+T[i]。可以构造如下矩阵:

[ S i T i T i − 1 T i − 1 ] = [ 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 0 ] × [ S i − 1 T i − 1 T i − 2 T i − 3 ] \begin{bmatrix} S_i\\ T_i\\ T_{i-1}\\ T_{i-1}\\ \end{bmatrix}= \begin{bmatrix} 1&1&1&1\\ 0&1&1&1\\ 0&1&0&0\\ 0&0&1&0\\ \end{bmatrix} \times \begin{bmatrix} S_{i-1}\\ T_{i-1}\\ T_{i-2}\\ T_{i-3}\\ \end{bmatrix} ⎣⎢⎢⎡​Si​Ti​Ti−1​Ti−1​​⎦⎥⎥⎤​=⎣⎢⎢⎡​1000​1110​1101​1100​⎦⎥⎥⎤​×⎣⎢⎢⎡​Si−1​Ti−1​Ti−2​Ti−3​​⎦⎥⎥⎤​

#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int mod=1000000007;
int aCP[4][4]={{1,1,1,1},{0,1,1,1},{0,1,0,0},{0,0,1,0}},bCP[4]={3,1,1,1},a[4][4],b[4];void mul(){int c[4];memset(c,0,sizeof(c));for(int j=0;j<4;j++)for(int k=0;k<4;k++)c[j]=(c[j]+a[j][k]*b[k])%mod;memcpy(b,c,sizeof(b));
}void mulSelf(){int c[4][4];memset(c,0,sizeof(c));for(int i=0;i<4;i++)for(int j=0;j<4;j++)for(int k=0;k<4;k++)c[i][j]=(c[i][j]+a[i][k]*a[k][j])%mod;memcpy(a,c,sizeof(a));
}int calc(int n){memcpy(a,aCP,sizeof(a));memcpy(b,bCP,sizeof(b));if(n<=2)    return n+1;n-=2;for(;n;n>>=1){if(n&1) mul();mulSelf();}return b[0];
}signed main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int x,y;while(cin>>x>>y){cout<<(calc(y)-calc(x-1)+mod)%mod<<'\n';    //防止结果为负}
}

Another kind of FibonacciProblem Description

As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , $S(N) = A ( 0 ) 2 + A ( 1 ) 2 + … … + A ( n ) 2 A(0)^2 +A(1)^2+……+A(n)^2 A(0)2+A(1)2+……+A(n)2.

Input

There are several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 2 31 2^{31} 231 – 1
X : 2<= X <= 2 31 2^{31} 231– 1
Y : 2<= Y <= 2 31 2^{31} 231 – 1

Output

For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.

Sample Input

2 1 1
3 2 3

Sample Output

6
196

Author

wyb

Source

HDOJ Monthly Contest – 2010.02.06

思路

设S[n]为A[n]平方的前缀和,显然: S [ i ] = S [ i − 1 ] + A [ i ] 2 S[i]=S[i-1]+A[i]^2 S[i]=S[i−1]+A[i]2
又 A [ i ] = X A [ i − 1 ] + Y A [ i − 2 ] A[i]=XA[i-1]+YA[i-2] A[i]=XA[i−1]+YA[i−2],那么:
A [ i ] 2 = X 2 A [ i − 1 ] 2 + 2 X Y A [ i − 1 ] A [ i − 2 ] + Y 2 A [ i − 2 ] 2 A[i]^2=X^2A[i-1]^2+2XYA[i-1]A[i-2]+Y^2A[i-2]^2 A[i]2=X2A[i−1]2+2XYA[i−1]A[i−2]+Y2A[i−2]2
并且 A [ i ] A [ i − 1 ] = X A [ i − 1 ] 2 + Y A [ i − 1 ] A [ i − 2 ] A[i]A[i-1]=XA[i-1]^2+YA[i-1]A[i-2] A[i]A[i−1]=XA[i−1]2+YA[i−1]A[i−2]
所以可以构造矩阵:
[ S i A i 2 A i − 1 2 A i A i − 1 ] = [ 1 x 2 y 2 2 x y 0 x 2 y 2 2 x y 0 1 0 0 0 x 0 y ] × [ S i − 1 A i − 1 2 A i − 2 2 A i − 1 A i − 2 ] \begin{bmatrix} S_i\\ A^2_i\\ A^2_{i-1}\\ A_iA_{i-1}\\ \end{bmatrix}= \begin{bmatrix} 1&x^2&y^2&2xy\\ 0&x^2&y^2&2xy\\ 0&1&0&0\\ 0&x&0&y\\ \end{bmatrix} \times \begin{bmatrix} S_{i-1}\\ A^2_{i-1}\\ A^2_{i-2}\\ A_{i-1}A_{i-2}\\ \end{bmatrix} ⎣⎢⎢⎡​Si​Ai2​Ai−12​Ai​Ai−1​​⎦⎥⎥⎤​=⎣⎢⎢⎡​1000​x2x21x​y2y200​2xy2xy0y​⎦⎥⎥⎤​×⎣⎢⎢⎡​Si−1​Ai−12​Ai−22​Ai−1​Ai−2​​⎦⎥⎥⎤​

#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int mod=10007;
int a[4][4],b[4];void mul(){int c[4];memset(c,0,sizeof(c));for(int j=0;j<4;j++)for(int k=0;k<4;k++)c[j]=(c[j]+a[j][k]*b[k])%mod;memcpy(b,c,sizeof(c));
}void mulSelf(){int c[4][4];memset(c,0,sizeof(c));for(int i=0;i<4;i++)for(int j=0;j<4;j++)for(int k=0;k<4;k++)c[i][j]=(c[i][j]+a[i][k]*a[k][j])%mod;memcpy(a,c,sizeof(a));
}signed main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);int n,x,y;while(cin>>n>>x>>y){x%=mod;y%=mod;a[0][0]=1,a[0][1]=x*x%mod,a[0][2]=y*y%mod,a[0][3]=2*x*y%mod;a[1][0]=0,a[1][1]=x*x%mod,a[1][2]=y*y%mod,a[1][3]=2*x*y%mod;a[2][0]=0,a[2][1]=1,a[2][2]=0,a[2][3]=0;a[3][0]=0,a[3][1]=x%mod,a[3][2]=0,a[3][3]=y%mod;b[0]=2,b[1]=1,b[2]=1,b[3]=1;for(n-=1;n;n>>=1){if(n&1) mul();mulSelf();}cout<<b[0]<<"\n";}
}

Kiki & Little Kiki 2

Problem Description

There are n lights in a circle numbered from 1 to n. The left of light 1 is light n, and the left of light k (1< k<= n) is the light k-1.At time of 0, some of them turn on, and others turn off.
Change the state of light i (if it’s on, turn off it; if it is not on, turn on it) at t+1 second (t >= 0), if the left of light i is on !!! Given the initiation state, please find all lights’ state after M second. (2<= n <= 100, 1<= M<= 1 0 8 10^8 108)

Input

The input contains one or more data sets. The first line of each data set is an integer m indicate the time, the second line will be a string T, only contains ‘0’ and ‘1’ , and its length n will not exceed 100. It means all lights in the circle from 1 to n.
If the ith character of T is ‘1’, it means the light i is on, otherwise the light is off.

Output

For each data set, output all lights’ state at m seconds in one line. It only contains character ‘0’ and '1.

Sample Input

1
0101111
10
100000001

Sample Output

1111000
001000010

Source

HDU 8th Programming Contest Site(1)

思路

d p [ i ] [ j ] = { d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − 1 ] = 0 d p [ i − 1 ] [ j ] ⊗ 1 , d p [ i − 1 ] [ j − 1 ] = 1 dp[i][j]=\left\{ \begin{aligned} dp[i-1][j] & ,dp[i-1][j-1]=0 \\ dp[i-1][j] \otimes1 & ,dp[i-1][j-1]=1 \end{aligned} \right. dp[i][j]={dp[i−1][j]dp[i−1][j]⊗1​,dp[i−1][j−1]=0,dp[i−1][j−1]=1​
当取mod=2时,上式化为:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d [ i − 1 ] [ j − 1 ] dp[i][j]=dp[i-1][j]+d[i-1][j-1] dp[i][j]=dp[i−1][j]+d[i−1][j−1]

#include<cstdio>
#include<cstring>
using namespace std;
const int mod=2,maxn=105;
int a[maxn][maxn],b[maxn],n,ch,len;void mul(){int c[maxn];memset(c,0,sizeof(c));for(int j=0;j<len;j++)for(int k=0;k<len;k++)c[j]=(c[j]+a[j][k]*b[k])%mod;memcpy(b,c,sizeof(b));
}void mulSelf(){int c[maxn][maxn];memset(c,0,sizeof(c));for(int i=0;i<len;i++)for(int j=0;j<len;j++)for(int k=0;k<len;k++)c[i][j]=(c[i][j]+a[i][k]*a[k][j])%mod;memcpy(a,c,sizeof(c));
}int main(){while(~scanf("%d",&n)){getchar();for(len=0;(ch=getchar())!='\n';len++)b[len]=ch-'0';for(int i=0;i<len;i++)a[i][i]=a[i][(i-1+len)%len]=1;for(;n;n>>=1){if(n&1) mul();mulSelf();}for(int i=0;i<len;i++)    putchar(b[i]+'0');puts("");memset(a,0,sizeof(a));}
}

杭电ACM-LCY算法进阶培训班-专题训练(矩阵快速幂)相关推荐

  1. 杭电ACM-LCY算法进阶培训班-专题训练15

    杭电ACM-LCY算法进阶培训班-专题训练(03-07-11-15) 1012 最短路 #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofa ...

  2. 杭电ACM-LCY算法进阶培训班-专题训练(计算几何入门)

    杭电ACM-LCY算法进阶培训班-专题训练(计算几何入门) 传送门 杭电ACM-LCY算法进阶培训班-专题训练(计算几何入门) Shape of HDU Problem Description Inp ...

  3. 杭电ACM-LCY算法进阶培训班-专题训练(KMP)

    杭电ACM-LCY算法进阶培训班-专题训练(KMP) 杭电ACM-LCY算法进阶培训班-专题训练(KMP) 剪花布条 Problem Description Input Output Sample I ...

  4. 2021-06-18杭电ACM-LCY算法进阶培训班-专题训练16

    杭电ACM-LCY算法进阶培训班-专题训练(04-08-12-16) 1009 Intervals #pragma GCC optimize(2) #pragma GCC optimize(3,&qu ...

  5. 杭电ACM-LCY算法进阶培训班-专题训练09

    杭电ACM-LCY算法进阶培训班-专题训练09 1014 剪花布条 #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast",& ...

  6. 杭电ACM-LCY算法进阶培训班-专题训练(线段树)

    杭电ACM-LCY算法进阶培训班-专题训练(线段树) 传送门 目录 杭电ACM-LCY算法进阶培训班-专题训练(线段树) 张煊的金箍棒(2) Problem Description Input Out ...

  7. 杭电ACM-LCY算法进阶培训班-专题训练(强连通分量)

    点对统计 最大点权 点对统计 Problem Description 给定一个有向图,统计有多少点对u,v(1≤u<v≤n)u,v(1≤u<v≤n)u,v(1≤u<v≤n)满足uuu ...

  8. 算法分类整理+模板①:矩阵快速幂

    一直有一个想法,感觉自己很多基础算法不是很扎实,想要找个机会写一些算法的整理,顺便自己总结一些实用的模板. 最近偶然在训练赛中连续做了2道思维+矩阵快速幂的题目,碰巧有时间,就以矩阵快速幂作为这个系列 ...

  9. 矩阵小专题(矩阵快速幂+矩阵加速)

    1.什么是矩阵? 矩阵(数学术语)_百度百科 2.矩阵快速幂 首先要知道,只有n*n的矩阵能乘以自身(否则不符合矩阵相乘的条件) 然后要明白普通的快速幂的原理(本质是把幂次二分,代码如下) inlin ...

最新文章

  1. 一个比较保守的404页面
  2. 20、计算机图形学——微平面理论和Cook-Torrance BRDF
  3. 解决docker pull 速度慢问题
  4. VMware Workstation 14 激活码
  5. 方案二、三SELECT、UDP完成聊天室
  6. 安装SQL2000 提示 以前的某个程序安装已在安装计算机上创建挂起的文件
  7. (48)FPGA三态多驱动(tri型)
  8. AD+邮件服务器搭建方案
  9. swagger注释API详细说明
  10. Warning the user/local/mysql/data directory is not owned by the mysql user
  11. AndroidStudio配置NDK
  12. win10鼠标指针修改
  13. Excel技能培训之十二 基本函数if,sumif,sumifs,clean,trim,upper,lower,proper,Text,REPLACE,substitute
  14. 图像特征的特点及其常用的特征提取与匹配方法
  15. MUI框架学习(2)-页面间传值
  16. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java社区闲置物品交易平台z10mc
  17. 《输赢》精彩段落总结
  18. python写入文件没反应_python写入文本 如何用python将变量及其值写入文本文件?...
  19. 汇千网-赴港上市升温 忙到日程排不下 港交所“红利期”来了
  20. Android - kotlin 协程极简入门

热门文章

  1. 医美面膜商城小程序开发,助力企业数字化转型
  2. java中数组的引用是什么意思_java中的数组是引用数据类型。
  3. DSP-FTU实现DNP3.0
  4. 语音转文字转换器市场现状研究分析-
  5. Linux:使用 redis 连接指定端口的 redis 数据库
  6. 一、创建线程的三种方式
  7. IDEA2022 配置spark开发环境
  8. 几个串口通信协议的整理
  9. 微信小程序输入框input
  10. 2022-2028年全球与中国饲料核苷酸行业市场需求预测分析