1. 程式人生 > 實用技巧 >HDU6395 Sequence(分塊+矩陣快速冪)

HDU6395 Sequence(分塊+矩陣快速冪)

對於這一類轉移次數很多的,肯定是考慮矩陣快速冪比較有效

對於狀態設計,就是把有用的狀態和常數放到狀態矩陣中

然後構造出轉移矩陣,對於本題因為p/n的答案不定,所以考慮整除分塊後,分塊求取答案

#include<bits/stdc++.h>
#define getsz(p) (p?p->sz:0)
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=3e5+10;
struct node{
    ll a[5][5];
    node(){
        memset(a,0,sizeof
a); } }s; node operator *(node a,node b){ node tmp; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++) tmp.a[i][j]=(tmp.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod; } } return tmp; } node martixpow(node x,int k){ node tmp;
for(int i=0;i<3;i++){ tmp.a[i][i]=1; } while(k){ if(k&1){ tmp=tmp*x; } k>>=1; x=x*x; } return tmp; } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ ll a,b,c,d,p,n; cin
>>a>>b>>c>>d>>p>>n; if(n==1){ cout<<a<<endl; continue; } else if(n==2){ cout<<b<<endl; continue; } int r; for(int i=3;i<=n;){ int tmp=p/i; if(tmp==0) r=n; else{ r=min(n,p/tmp); } node t; t.a[0][0]=d,t.a[0][1]=c,t.a[0][2]=tmp; t.a[1][0]=1,t.a[2][2]=1; t=martixpow(t,r-i+1); int tmpb=(t.a[0][0]*b+t.a[0][1]*a+t.a[0][2])%mod; int tmpa=(t.a[1][0]*b+t.a[1][1]*a+t.a[1][2])%mod; a=tmpa; b=tmpb; i=r+1; } cout<<b<<endl; } return 0; }
View Code