[TopCoder11557]MatrixPower
Posted zhoushuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[TopCoder11557]MatrixPower相关的知识,希望对你有一定的参考价值。
description
你有一个(n imes n)的矩阵(A),下标从(0)开始,其中(A_{i,j}=di + q^i)。
给你(d,q,n,k,s,t),求((A^k)_{s,t})的值模(10^9+7)。
(nle10^4,d,q,kle10^9,0le s,t <n)
sol
先写出一个极其丑陋的柿子:
[(A^k)_{s,t}=sum_{x_1}sum_{x_2}...sum_{x_{k-1}}(ds+q^{x_1})(dx_1+q^{x_2})...(dx_{k-1}+q^t)]
等于你从(s)出发走(k)次走到(t),那么中间就有(k-1)个位置可以任选,所以才会有前面的(k-1)个(sum)。
把后面的括号暴力展开,一共有(2^k)项。然而还是做不了。
考虑每个(x_i)。它出现在答案中的形式只有(4)种:(1,dx_i,q_{x_i},dx_iq^{x_i})。这取决于这个(x_i)出现的两个相邻的括号内取的是哪一个。
预处理出(sd=sum_{i=0}^{n-1}di,sq=sum_{i=0}^{n-1}q^i,ss=sum_{i=0}^{n-1}diq^i)。
设(f_{i,0/1})表示考虑了前(i)个括号,第(i)个括号取的是前一项/后一项时,只计算前(i-1)个(x_i)时的答案。显然有转移式:
[f_{i+1,0}=f_{i,0} imes sd+f_{i,1} imes ss\f_{i+1,1}=f_{i,0} imes n+f_{i,1} imes sq]
初值(f_{1,0}=ds,f_{1,1}=1)。最后一次转移特判一下(因为最后一个(x)必须强制为(t))。
这样就可以做(O(k))的(dp)了。考虑到每次的转移都是一样的,所以直接矩乘就好了。
code
为什么没有人告诉我,定义在(mbox{class})里面的变量的初值不是(0)。
害我浪费了宝贵的(mbox{20min})才发现这个错误(mbox{qwq})。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 10005;
const int mod = 1e9+7;
int fastpow(int a,int b){
int s=1;
while (b) {if (b&1) s=1ll*s*a%mod;a=1ll*a*a%mod;b>>=1;}
return s;
}
struct matrix{
int a[2][2];
matrix(){memset(a,0,sizeof(a));}
matrix(int q,int w,int d,int b){
a[0][0]=q;a[0][1]=w;a[1][0]=d;a[1][1]=b;
}
int* operator [](int x){return a[x];}
matrix operator * (matrix &b){
matrix c;
for (int i=0;i<2;++i)
for (int j=0;j<2;++j)
for (int k=0;k<2;++k)
c[i][k]=(1ll*a[i][j]*b[j][k]+c[i][k])%mod;
return c;
}
}S,T,A,B;
class MatrixPower{
public:
int m,sd,sq,ss;vector<int>ans;
vector<int> getElements(int d,int q,int n,int k,vector<int>r,vector<int>c){
m=r.size();ans.resize(m);
if (k==1){
for (int i=0;i<m;++i) ans[i]=(1ll*d*r[i]+fastpow(q,c[i]))%mod;
return ans;
}
k-=2;sd=sq=ss=0;
for (int i=0;i<n;++i) sd=(sd+1ll*d*i)%mod;
for (int i=0;i<n;++i) sq=(sq+fastpow(q,i))%mod;
for (int i=0;i<n;++i) ss=(ss+1ll*d*i%mod*fastpow(q,i))%mod;
T=matrix(sd,n,ss,sq);S=matrix(1,0,0,1);
while (k) {if (k&1) S=S*T;T=T*T;k>>=1;}
for (int i=0;i<m;++i){
A=matrix(1ll*d*r[i]%mod,1,0,0);
B=matrix(sd,1ll*n*fastpow(q,c[i])%mod,ss,1ll*sq*fastpow(q,c[i])%mod);
A=A*S*B;
ans[i]=(1ll*A[0][0]+A[0][1]+A[1][0]+A[1][1])%mod;
}
return ans;
}
};
以上是关于[TopCoder11557]MatrixPower的主要内容,如果未能解决你的问题,请参考以下文章