bzoj 3231 SDOI2008 遞迴數列

2021-08-08 09:19:14 字數 1404 閱讀 9727

乙個由自然數組成的數列按下式定義:

對於i <= k:a[i]= b[i]

對於i > k: a[i] = c[1]*a[i-1] + c[2]*a[i-2] + …+ c[k]*a[i-k]

其中b[j]和 c[j] (1<=j<=k)是給定的自然數。寫乙個程式,給定自然數m <= n, 計算a[m] + a[m+1] + a[m+2] + … + a[n], 並輸出它除以給定自然數p的餘數的值。

這道題的演算法顯而易見是矩陣乘法與快速冪。只不過麻煩了一點,其餘的地方還是比較基礎的。講一下矩陣構造吧,首先假設k=4,那麼初始序列為a[1]~a[4],s[4]。s陣列的意思挺好理解,舉個例子,s[i]就表示a[1]+a[2]+…+a[i]。下圖為相乘過程,中的第乙個矩陣為半成品結果矩陣,由此可以得到構造半成品結果矩陣的規律。a[i][i+1]=1(1<=i,k>i),a[k][k-i+1]=a[k+1][k-i+1]=c[i](1<=i, k>=i),a[k+1][k+1]=1。為什麼這樣?已經告訴你了。得到構造半成品結果矩陣後,就很簡單了。用兩次快速冪,再乘初始序列,算出s[m-1]與s[n],再相減,這題便解決了。當然有些情況需要特殊判斷一下,所以這題才會麻煩。

for(int i=1;i<=n;i++)//構造構造半成品結果矩陣

per.a[n+1][n+1]=1;

scanf("%lld%lld%lld",&l,&r,&p);

l--;

if(l<=n)s1=s[l];

else

if(bk==false)n--;

if(r<=n)s2=s[r];

else

printf("%lld\n",((s2-s1)%p+p)%p);//一定要這樣加p後再mod p,本題的乙個大坑點

return

0;}

BZOJ3231 Sdoi2008 遞迴數列

bzoj3231 sdoi2008 遞迴數列 乙個由自然數組成的數列按下式定義 對於i k ai bi 對於i k ai c1ai 1 c2ai 2 ckai k 其中bj 和 cj 1 j k 是給定的自然數。寫乙個程式,給定自然數m n,計算am am 1 am 2 an 並輸出它除以給定自然數...

BZOJ 3231 Sdoi2008 遞迴數列

bzoj 3231 sdoi2008 遞迴數列 矩陣乘法 乙個由自然數組成的數列按下式定義 對於i k ai bi 對於i k ai c1ai 1 c2ai 2 ckai k 其中bj 和cj 1 j k 是給定的自然數。寫乙個程式,給定自然數m n,計算am am 1 am 2 an 並輸出它除以...

BZOJ3231 矩陣連乘,稍有點複雜

題目 3231 sdoi2008 遞迴數列 題意 乙個由自然數組成的數列按下式定義 對於 i k ai bi 對於 i k ai c1ai 1 c2ai 2 ckai k 其中bj和 cj 1 j k 是給定的自然數。寫乙個程式,給定自然數 m n,計算am am 1 am 2 an 並輸出它除以給...