您的位置:首页 > 其它

矩阵快速幂大合集

2015-05-30 18:54 281 查看
hdu1757:

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(k);

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 10;
int a
,k,m;
struct mat {
int g

;
mat operator*(mat a) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
for(int k = 0; k < 10; k++) {
tmp.g[i][j]	= (tmp.g[i][j] + this->g[i][k] * a.g[k][j]) % m;
}
}
}
return tmp;
}
}res,ori;
void cul(int n) {
while(n) {
if(n & 1)
res = res * ori;
n >>= 1;
ori = ori * ori;
}
printf("%d\n", res.g[0][0]);
}
int main() {
while(scanf("%d%d",&k,&m) != EOF) {
memset(res.g, 0, sizeof(res.g));
memset(ori.g, 0, sizeof(ori.g));
for(int i = 0; i < 10; i++) {
scanf("%d",&ori.g[i][0]);
res.g[0][i] = 9 - i;
}
for(int i = 0; i < 9; i++) {
ori.g[i][i + 1] = 1;
}
cul(k - 9);
}
}


hdu1575

Description

A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。

Input

数据的第一行是一个T,表示有T组数据。

每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。

Output

对应每组数据,输出Tr(A^k)%9973。

Sample Input

2
2 2
1 0
0 1
3 99999999
1 2 3
4 5 6
7 8 9


Sample Output

2
2686


求矩阵A的k次方的对角线和(模板题)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct mat {
int g[10][10];
}res,ori;

int n,k;
mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < n; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % 9973;
}
}
}
return tmp;
}
void cul(int k) {
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
int ans  = 0;
for(int i = 0; i < n; i++) {
ans = (ans + res.g[i][i]) % 9973;
}
printf("%d\n",ans);
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&k);
memset(res.g, 0, sizeof(res.g));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
scanf("%d",&res.g[i][j]);
}
}
ori = res;
cul(k - 1);
}
}


hdu2604

Description

Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.



Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2 L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue
else it is a E-queue.

Your task is to calculate the number of E-queues mod M with length L by writing a program.

Input

Input a length L (0 <= L <= 10 6) and M.

Output

Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.

Sample Input

3 8
4 7
4 8


Sample Output

6
2
1


题意:一个序列只有f和m问长度为L的序列,不含fmf和fff的有几个;

思路:

结尾总共有四种

ff,fm,mf,ff

以ff结尾的再加一位,可以推出fm结尾,即ffm(不能推出ff,因为这样就有fff了)

以fm结尾能推出mm;以mm结尾能推出mm和mf;

以mm结尾的能推出mm和mf;

然后就能构造矩阵乘:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct mat {
int g[4][4];
}res, ori;

int n,m;
mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
for(int k = 0; k < 4; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % m;
}
}
}
return tmp;
}
void cul(int k) {
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
int ans = 0;
for(int i = 0; i < 4; i++) {
ans = (ans + res.g[0][i]) % m;
}
printf("%d\n",ans);
}
int main() {
while(scanf("%d%d",&n,&m) != EOF) {
if(n == 0) {
printf("0\n");
continue;
}else if(n == 1) {
printf("2\n");
continue;
}else if(n == 2) {
printf("4\n");
continue;
}
memset(ori.g, 0, sizeof(ori.g));
memset(res.g, 0, sizeof(res.g));
ori.g[0][3] = 1;
ori.g[1][0] = 1;
ori.g[2][0] = 1;
ori.g[2][1] = 1;
ori.g[3][2] = 1;
ori.g[3][3] = 1;
for(int i = 0; i < 4; i++)
res.g[0][i] = 1;
cul(n - 2);
}
}


hdu2256

Description



Input

The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n. (1 <= n <= 10^9)

Output

For each input case, you should output the answer in one line.

Sample Input

3
1
2
5


Sample Output

9
97
841


#include<cstdio>
#include<cstring>
#include<cmath>

struct mat {
int g[2][2];
}res, ori;
int n;
mat mul(mat a,mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
for(int k = 0; k < 2; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j])%1024;
}
}
}
return tmp;
}
void cul(int k) {
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
int ans = (res.g[0][0] * 5 + res.g[0][1] * 2) %1024;
printf("%d\n",(ans * 2 - 1) % 1024);
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
if(n == 1) {
printf("9\n");
continue;
}
ori.g[0][0] = 5;
ori.g[0][1] = 12;
ori.g[1][0] = 2;
ori.g[1][1] = 5;
res = ori;
cul(n - 2);
}
}


hdu2276

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<= 10^8)

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


#include<cstdio>
#include<cstring>
#define ll long long
struct mat {
int g[105][105];
}res, ori;
int n, len;
char str[105];
char change[2] = {'1','0'};
mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
tmp.g[0][i] = (tmp.g[0][i] + a.g[0][j] * b.g[j][i]) % 2;
}
}
return tmp;
}
mat mul2(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < len; i++) {
for(int j = 0; j < len; j++) {
for(int k = 0; k < len; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % 2;
}
}
}
return tmp;
}
void cul(int k){
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul2(ori, ori);
}
for(int i = 0; i <len; i++) {
printf("%d",res.g[0][i]);
}
printf("\n");
}
int main() {
while(scanf("%d",&n) != EOF) {
scanf("%s",str);
len = strlen(str);
memset(ori.g, 0, sizeof(ori.g));
memset(res.g, 0, sizeof(res.g));
for(int i = 0; i < len; i++) {
res.g[0][i] = str[i] - '0';
}
for(int i = 0; i < len; i++) {
if(i == 0)
ori.g[i][i] = ori.g[len - 1][i] = 1;
else
ori.g[i][i] = ori.g[i - 1][i] = 1;
}
cul(n);
}
}


hdu4686

Description

An Arc of Dream is a curve defined by following function:



where

a 0 = A0

a i = a i-1*AX+AY

b 0 = B0

b i = b i-1*BX+BY

What is the value of AoD(N) modulo 1,000,000,007?

Input

There are multiple test cases. Process to the End of File.

Each test case contains 7 nonnegative integers as follows:

N

A0 AX AY

B0 BX BY

N is no more than 10 18, and all the other integers are no more than 2×10 9.

Output

For each test case, output AoD(N) modulo 1,000,000,007.

Sample Input

 1
1 2 3
4 56 2 12 3
4 5 6
3
1 2 3
4 5 6


Sample Output

4
134
1902


#include<cstdio>
#include<cstring>
#define ll long long

const ll mod = 1000000007;
struct mat{
ll g[5][5];
}res, ori;

mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
for(int k = 0; k < 5; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j])%mod;
}
}
}
return tmp;
}
void cul(ll k){
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
printf("%lld\n",res.g[0][0]);
}
ll a0,ax,ay;
ll b0,bx,by;
ll n;
int main() {
while(scanf("%lld",&n) != EOF) {
memset(res.g,0,sizeof(res.g));
memset(ori.g,0,sizeof(ori.g));
scanf("%lld%lld%lld%lld%lld%lld",&a0,&ax,&ay,&b0,&bx,&by);
res.g[0][1]=a0 * b0 % mod;
res.g[0][2]=a0 % mod;
res.g[0][3]=b0 % mod;
res.g[0][4]=1;
ori.g[0][0]=1;
ori.g[1][0]=1;
ori.g[1][1]=(ax * bx) % mod;
ori.g[2][1]=ax * by % mod;
ori.g[2][2]=ax % mod;
ori.g[3][1]=bx * ay % mod;
ori.g[3][3]=bx % mod;
ori.g[4][1]=ay * by % mod;
ori.g[4][2]=ay % mod;
ori.g[4][3]=by % mod;
ori.g[4][4]=1;
cul(n);
}
return 0;
}


zoj3690

Description

There are n people standing in a row. And There are m numbers, 1.2...m. Every one should choose a number. But if two persons standing adjacent to each other choose the same number, the number shouldn't equal or less than k.
Apart from this rule, there are no more limiting conditions.

And you need to calculate how many ways they can choose the numbers obeying the rule.

Input

There are multiple test cases. Each case contain a line, containing three integer n (2 ≤ n ≤ 108), m (2 ≤ m ≤ 30000), k(0 ≤ k ≤ m).

Output

One line for each case. The number of ways module 1000000007.

Sample Input

4 4 1


Sample Output

216


#include<cstdio>
#include<cstring>
#define ll long long

struct mat {
ll g[2][2];
}res, ori, ans;
ll n,m,k;
const ll M = 1000000007;
mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
for(int k = 0; k < 2; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % M;
}
}
}
return tmp;
}
void cul(int l){
while(l) {
if(l & 1)
res = mul(res, ori);
l >>= 1;
ori = mul(ori, ori);
}
ll sum = 0;
sum = (sum + (res.g[0][0] * (m - k) % M)) % M;
sum = (sum + (res.g[0][1] *  k % M)) % M;
sum = (sum + (res.g[1][0] * (m - k) % M)) % M;
sum = (sum + (res.g[1][1] * k % M)) % M;
printf("%lld\n",sum);
}
int main() {
while(scanf("%lld%lld%lld",&n,&m,&k) != EOF) {
memset(ori.g, 0, sizeof(ori.g));
memset(res.g, 0, sizeof(res.g));
ori.g[0][0] = m-k;
ori.g[0][1] = m-k;
ori.g[1][0] = k;
ori.g[1][1] = k - 1;
res.g[0][1] = res.g[1][0] = 0;
res.g[0][0] = res.g[1][1] = 1;
cul(n - 1);
}
}


FZU1683

Description

已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给定的每个n,输出F(0)+ F(1)+ …… + F(n) mod 2009。

Input

第一行是一整数m,代表总共有m个cases。

Output

对于每个case,输出一行。格式见样例,冒号后有一个空格。

Sample Input

236

Sample Output

Case 1: 37Case 2: 313

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct mat{
int g[4][4];
}res, ori;
int n;
int cas = 1;

mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
for(int k = 0; k < 4; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % 2009;
}
}
}
return tmp;
}
mat mul2(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
tmp.g[0][i] = (tmp.g[0][i] + a.g[0][j] * b.g[j][i]) % 2009;
}
}
return tmp;
}
void cul(int k) {
while(k) {
if(k & 1)
res = mul2(res,ori);
k >>= 1;
ori = mul(ori, ori);
}
printf("Case %d: %d\n",cas++,res.g[0][3]);
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
if(n == 0) {
printf("Case %d: 1\n",cas++);
continue;
}else if(n == 1) {
printf("Case %d: 4\n",cas++);
continue;
}else if(n == 2) {
printf("Case %d: 9\n",cas++);
continue;
}
memset(res.g, 0, sizeof(res.g));
memset(ori.g, 0, sizeof(ori.g));
res.g[0][0] = 5, res.g[0][1] = 3, res.g[0][2] = 1, res.g[0][3] = 9;
ori.g[0][0] = 3, ori.g[1][0] = 2, ori.g[2][0] = 7;
ori.g[0][1] = 1, ori.g[1][2] = 1;
ori.g[0][3] = 3;
ori.g[1][3] = 2;
ori.g[2][3] = 7;
ori.g[3][3] = 1;
cul(n - 2);
}
return 0;
}


hdu3306

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.

Input

There are several test cases.

Each test case will contain three integers , N, X , Y .

N : 2<= N <= 2 31 � 1

X : 2<= X <= 2 31� 1

Y : 2<= Y <= 2 31 � 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


#include<cstdio>
#include<cstring>
#define ll long long
struct mat {
ll g[4][4];
}res, ori, ans;
ll n,x,y;
mat mul(mat a, mat b) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
for(int k = 0; k < 4; k++) {
tmp.g[i][j] = (tmp.g[i][j] + a.g[i][k] * b.g[k][j]) % 10007;
}
}
}
return tmp;
}
void cul(ll k){
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
printf("%lld\n",res.g[0][0]);
}
int main() {
while(scanf("%lld%lld%lld",&n,&x,&y) != EOF) {
memset(ori.g, 0, sizeof(ori.g));
memset(res.g, 0, sizeof(res.g));
ori.g[0][0] = 1;
ori.g[1][0] = 1;
ori.g[1][1] = (x * x) % 10007;
ori.g[1][2] = 1;
ori.g[1][3] = x % 10007;
ori.g[2][1] = (y * y) % 10007;
ori.g[3][1] = (2 * x * y) % 10007;
ori.g[3][3] = y % 10007;
res.g[0][0] = 1;
res.g[0][1] = 1;
res.g[0][2] = 1;
res.g[0][3] = 1;
cul(n);
}
}


hdu4565

Description

  A sequence S n is defined as:



Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate S n.

  You, a top coder, say: So easy!



Input

  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 2 15, (a-1) 2< b < a2, 0 < b, n < 2 31.The input will finish with
the end of file.

Output

  For each the case, output an integer S n.

Sample Input

2 3 1 2013
2 3 2 2013
2 2 1 2013


Sample Output

4
14
4


#include<cstdio>
#include<cstring>
#define ll long long

struct mat {
ll g[2][2];
}res, ori;

ll a,b, m;
ll n;
mat mul(mat c, mat d) {
mat tmp;
memset(tmp.g, 0, sizeof(tmp.g));
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
for(int k = 0; k < 2; k++) {
tmp.g[i][j] = (tmp.g[i][j] + c.g[i][k] * d.g[k][j]) % m;
}
}
}
return tmp;
}
void cul(ll k) {
while(k) {
if(k & 1)
res = mul(res, ori);
k >>= 1;
ori = mul(ori, ori);
}
ll ans =(res.g[0][0] * 2)% m;
printf("%lld\n",ans);
}
int main() {
while(scanf("%lld%lld%lld%lld",&a,&b,&n,&m) != EOF) {
memset(ori.g, 0, sizeof(ori.g));
ori.g[0][0] = a;
ori.g[0][1] = b;
ori.g[1][0] = 1;
ori.g[1][1] = a;
res = ori;
cul(n - 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: