集训队专题(2)中,1003矩阵幂级数如何应用?

2026-05-29 13:263阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计827个文字,预计阅读时间需要4分钟。

集训队专题(2)中,1003矩阵幂级数如何应用?

题目:矩阵幂级数时间限制:6000/3000ms(Java/其他)内存限制:262144/131072K(Java/其他)总提交次数:51通过提交次数:26题目描述:给定一个n阶矩阵A和一个正整数k,求矩阵幂级数的和S=A + A^2 + A^3...+ A^k


Matrix Power Series

Time Limit : 6000/3000ms (Java/Other)Memory Limit : 262144/131072K (Java/Other)
Total Submission(s) : 51Accepted Submission(s) : 26

Problem Description

Given an×nmatrixAand a positive integerk, find the sumS=A+A2+A3+ … +Ak.


Input

The input contains exactly one test case. The first line of input contains three positive integersn(n≤ 30),k(k≤ 109) andm(m< 104). Then follownlines each containingnnonnegative integers below 32,768, givingA’s elements in row-major order.


Output

Output the elements ofSmodulomin the same way asAis given.


Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3


Source

PKU

此题是快速幂的一个相当经典的变形运用,求A + A^2 + A^3 + ... + A^k的结果。

这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。

集训队专题(2)中,1003矩阵幂级数如何应用?

比如,当k=6时,有:
A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3)+ A^3*(A + A^2 + A^3)
应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,k,mod;
struct Matrix
{
int arr[40][40];
};
Matrix unit,init;
Matrix Mul(Matrix a,Matrix b)
{
Matrix c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
c.arr[i][j]=0;
for(int k=0;k<n;k++)
c.arr[i][j]=(c.arr[i][j]+a.arr[i][k]*b.arr[k][j]%mod)%mod;
c.arr[i][j]%=mod;
}
return c;
}
Matrix Pow(Matrix a,Matrix b,int x)
{
while(x)
{
if(x&1)
{
b=Mul(b,a);
}
x>>=1;
a=Mul(a,a);
}
return b;
}
Matrix Add(Matrix a,Matrix b)
{
Matrix c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
c.arr[i][j]=(a.arr[i][j]+b.arr[i][j])%mod;
return c;
}
Matrix solve(int x)
{
if(x==1)
return init;
Matrix res=solve(x/2),cur;
if(x&1)
{
cur=Pow(init,unit,x/2+1);
res=Add(res,Mul(cur,res));
res=Add(res,cur);
}
else
{
cur=Pow(init,unit,x/2);
res=Add(res,Mul(cur,res));
}
return res;
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&mod))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&init.arr[i][j]);
unit.arr[i][j]=(i==j?1:0);
}
Matrix res=solve(k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n-1;j++)
printf("%d ",res.arr[i][j]);
printf("%d\n",res.arr[i][n-1]);
}
}
return 0;
}



本文共计827个文字,预计阅读时间需要4分钟。

集训队专题(2)中,1003矩阵幂级数如何应用?

题目:矩阵幂级数时间限制:6000/3000ms(Java/其他)内存限制:262144/131072K(Java/其他)总提交次数:51通过提交次数:26题目描述:给定一个n阶矩阵A和一个正整数k,求矩阵幂级数的和S=A + A^2 + A^3...+ A^k


Matrix Power Series

Time Limit : 6000/3000ms (Java/Other)Memory Limit : 262144/131072K (Java/Other)
Total Submission(s) : 51Accepted Submission(s) : 26

Problem Description

Given an×nmatrixAand a positive integerk, find the sumS=A+A2+A3+ … +Ak.


Input

The input contains exactly one test case. The first line of input contains three positive integersn(n≤ 30),k(k≤ 109) andm(m< 104). Then follownlines each containingnnonnegative integers below 32,768, givingA’s elements in row-major order.


Output

Output the elements ofSmodulomin the same way asAis given.


Sample Input

2 2 4
0 1
1 1

Sample Output

1 2
2 3


Source

PKU

此题是快速幂的一个相当经典的变形运用,求A + A^2 + A^3 + ... + A^k的结果。

这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。

集训队专题(2)中,1003矩阵幂级数如何应用?

比如,当k=6时,有:
A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3)+ A^3*(A + A^2 + A^3)
应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,k,mod;
struct Matrix
{
int arr[40][40];
};
Matrix unit,init;
Matrix Mul(Matrix a,Matrix b)
{
Matrix c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
c.arr[i][j]=0;
for(int k=0;k<n;k++)
c.arr[i][j]=(c.arr[i][j]+a.arr[i][k]*b.arr[k][j]%mod)%mod;
c.arr[i][j]%=mod;
}
return c;
}
Matrix Pow(Matrix a,Matrix b,int x)
{
while(x)
{
if(x&1)
{
b=Mul(b,a);
}
x>>=1;
a=Mul(a,a);
}
return b;
}
Matrix Add(Matrix a,Matrix b)
{
Matrix c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
c.arr[i][j]=(a.arr[i][j]+b.arr[i][j])%mod;
return c;
}
Matrix solve(int x)
{
if(x==1)
return init;
Matrix res=solve(x/2),cur;
if(x&1)
{
cur=Pow(init,unit,x/2+1);
res=Add(res,Mul(cur,res));
res=Add(res,cur);
}
else
{
cur=Pow(init,unit,x/2);
res=Add(res,Mul(cur,res));
}
return res;
}
int main()
{
while(~scanf("%d%d%d",&n,&k,&mod))
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
scanf("%d",&init.arr[i][j]);
unit.arr[i][j]=(i==j?1:0);
}
Matrix res=solve(k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n-1;j++)
printf("%d ",res.arr[i][j]);
printf("%d\n",res.arr[i][n-1]);
}
}
return 0;
}