HDU 6395 靈性優化
阿新 • • 發佈:2018-12-17
我知道為什麼這道題A的人這麼少了
由於數論分塊的特性
這個塊會在前邊特別密
來後又來個矩陣快速冪
複雜度會很高
還不如一個一個手推
和那個等差數列異或和的優化思想是一樣的
都是對數論分塊的前半部分的優化
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; typedef vector<ll> vec; typedef vector<vec> mat; ll Ans[100010]; mat mul(mat& A, mat& B){ mat C(A.size(), vec(B[0].size())); for (ll i = 0; i < A.size(); i++) for (ll k = 0; k < B.size(); k++) if (A[i][k]) // 對稀疏矩陣的優化 for (ll j = 0; j < B[0].size(); j++) C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod; return C; } mat Pow(mat A, int n){ mat B(A.size(), vec(A.size())); for (ll i = 0; i < A.size(); i++) B[i][i] = 1; for (; n; n >>= 1, A = mul(A, A)) if (n & 1) B = mul(B, A); return B; } int main(){ freopen("1.txt","r",stdin); int T; scanf("%d",&T); G: while(T--){ ll A,B,C,D,P,n; scanf("%lld%lld%lld%lld%lld%lld",&A,&B,&C,&D,&P,&n); mat AA(3,vec(3)); AA[0][0]=D;AA[0][1]=1;AA[0][2]=0; AA[1][0]=C;AA[1][1]=0;AA[1][2]=0; AA[2][0]=0;AA[2][1]=0;AA[2][2]=1; mat BB(1,vec(3)); mat CC(3,vec(3)); Ans[1]=A;Ans[2]=B; for(int i=3;i<=100000;++i)Ans[i]=(C*Ans[i-2]%mod+D*Ans[i-1%mod]+P/i)%mod; if(n<=100000){ cout<<Ans[n]<<endl; goto G; } BB[0][0]=Ans[100000];BB[0][1]=Ans[99999];BB[0][2]=1; for(ll i=100001;i<=P;++i){ ll x=P/(P/i); AA[2][0]=P/i; if(n<=x){ CC=Pow(AA,n-i+1); BB=mul(BB,CC); cout<<BB[0][0]<<endl; goto G; }else{ CC=Pow(AA,x-i+1); BB=mul(BB,CC); } i=x; } AA[2][0]=0; CC=Pow(AA,n-max(P,1ll*2)); BB=mul(BB,CC); cout<<BB[0][0]<<endl; } }