HDU - 6395 Sequence (整除分块+矩阵快速幂)
定义数列:
$\left\{\begin{eqnarray*} F_1 &=& A \\ F_2 &=& B \\ F_n &=& C\cdot{}F_{n-2}+D\cdot{}F_{n-1}+\left\lfloor\frac{P}{n}\right\rfloor \end{eqnarray*}\right.$
求该数列的第n项。
很明显的整除分块问题,把$\left\lfloor\frac{P}{n}\right\rfloor$相同n的分为一组进行矩阵快速幂即可。复杂度$O(3^3\sqrt nlogn)$
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10,mod=1e9+7; 5 int n,A,B,C,D,P; 6 struct Mat { 7 int a[3][3],n; 8 Mat() {memset(a,0,sizeof a),n=3;} 9 int* operator[](int x) {return a[x];} 10 Mat operator+(Mat b) { 11 Mat c; 12 for(int i=0; i<n; ++i) 13 for(int j=0; j<n; ++j) 14 c[i][j]=(a[i][j]+b[i][j])%mod; 15 return c; 16 } 17 Mat operator*(Mat b) { 18 Mat c; 19 for(int i=0; i<n; ++i) 20 for(int j=0; j<n; ++j) 21 for(int k=0; k<n; ++k) 22 c[i][j]=(c[i][j]+(ll)a[i][k]*b[k][j])%mod; 23 return c; 24 } 25 }; 26 Mat Pow(Mat x,int p) { 27 Mat ret; 28 for(int i=0; i<ret.n; ++i)ret[i][i]=1; 29 for(; p; p>>=1,x=x*x)if(p&1)ret=ret*x; 30 return ret; 31 } 32 int solve() { 33 if(n==1)return A; 34 Mat t; 35 for(int i=0; i<t.n; ++i)t[i][i]=1; 36 for(int l=3,r,k; l<=n; l=r+1) { 37 k=P/l,r=k&&P/k<n?P/k:n; 38 Mat x; 39 x[0][0]=D; 40 x[0][1]=C; 41 x[0][2]=k; 42 x[1][0]=1; 43 x[2][2]=1; 44 x=Pow(x,r-l+1); 45 t=x*t; 46 } 47 return ((ll)t[0][0]*B%mod+(ll)t[0][1]*A%mod+t[0][2])%mod; 48 } 49 int main() { 50 int T; 51 for(scanf("%d",&T); T--;) { 52 scanf("%d%d%d%d%d%d",&A,&B,&C,&D,&P,&n); 53 printf("%d\n",solve()); 54 } 55 return 0; 56 }