HDU - 6395 Sequence(分块+矩阵快速幂)
题意:
$
\begin{cases}
& F_{1} = A \\
& F_{2} = B \\
& F_{n} = C·F_{n-2} + D·F_{n-1}+\lfloor \frac{P}{n}\rfloor
\end{cases}
$
给定递推式,求$F_{n}\mod{1e9+7}$
思路:
一来就会想到用矩阵快速幂,但是其中有一个下取整就肯定不是裸的矩阵快速幂;
有向下取整我们就可以用分块来做,复杂度为$\sqrt{P}log_{2}P$
1 /* 2 * Author: windystreet 3 * Date : 2018-08-14 09:46:10 4 * Motto : Think twice, code once. 5 */ 6 #include<bits/stdc++.h> 7 8 using namespace std; 9 10 #define X first 11 #define Y second 12 #define eps 1e-5 13 #define gcd __gcd 14 #define pb push_back 15 #define PI acos(-1.0) 16 #define lowbit(x) (x)&(-x) 17 #define bug printf("!!!!!\n"); 18 #define mem(x,y) memset(x,y,sizeof(x)) 19 20 typedef long long LL; 21 typedef long double LD; 22 typedef pair<int,int> pii; 23 typedef unsigned long long uLL; 24 25 const int maxn = 1e5+7; 26 const int INF = 1<<30; 27 const int mod = 1e9+7; 28 29 struct Matrix 30 { 31 int n,m; 32 LL ma[5][5]; 33 Matrix (int x,int y):n(x),m(y){clear();} 34 void set(int n_,int m_){n = n_,m = m_;} 35 LL *operator[](int x){return ma[x];} 36 Matrix operator*(Matrix x){ 37 Matrix res(n,x.m); 38 for(int i=1;i<=n;i++) 39 for(int j=1;j<=x.m;j++) 40 for(int k=1;k<=m;k++) 41 (res[i][j]+=ma[i][k]*x[k][j]%mod+mod)%=mod; 42 return res; 43 } 44 Matrix operator ^(int y){ 45 Matrix x(n,m); 46 for(int i=1;i<=n;i++) 47 for(int j=1;j<=m;j++) 48 x[i][j]=ma[i][j]; 49 Matrix res(x.n,x.n); 50 for(int i=1;i<=x.n;i++) 51 res[i][i]=1; 52 for(;y;y>>=1,x=x*x) 53 if(y&1)res=res*x; 54 return res; 55 } 56 void print(){ 57 for(int i=1;i<=n;i++) 58 for(int j=1;j<=m;j++) 59 printf("%lld%c",ma[i][j]," \n"[j==m]); 60 } 61 void clear(){mem(ma,0);} 62 }; 63 int a ,b,c,d ,p,n; 64 pii f(int x,int y){ 65 if(!x)return make_pair(y,n); 66 int l = max(y,(p+x+1)/(x+1)),r = min(n,p/x); 67 return make_pair(l,r); 68 } 69 70 void solve(){ 71 scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&p,&n); 72 if(n==1)printf("%d\n",a); 73 if(n==2)printf("%d\n",b); 74 else{ 75 Matrix x(1,3),y(3,3); 76 x[1][1] = b,x[1][2]=a,x[1][3]=1; 77 for(int i=3;i<=n;){ 78 pii seg = f(p/i,i); 79 y[1][1]=d,y[1][2] = 1,y[1][3] = 0; 80 y[2][1]=c,y[2][2] = 0,y[2][3] = 0; 81 y[3][1]=p/i,y[3][2]=0,y[3][3] = 1; 82 x = x*(y^(seg.Y - seg.X + 1)); 83 i = seg.Y+1; 84 } 85 printf("%lld\n",x[1][1] ); 86 } 87 88 return; 89 } 90 91 int main() 92 { 93 // freopen("F:\\in.txt","r",stdin); 94 // freopen("out.txt","w",stdout); 95 // ios::sync_with_stdio(false); 96 int t = 1; 97 scanf("%d",&t); 98 while(t--){ 99 // printf("Case %d: ",cas++); 100 solve(); 101 } 102 return 0; 103 }