Description
A sequence of natural numbers is defined as follows:
For i <= K:ai = Bi
For i > K:ai = c1ai-1 + c2ai-2 + ... + ckai-k
Where BJ and CJ (1<=J<=K) are given the natural number. Write a program, given the natural number M <= N, calculate am + am+1 + am+2 + ... + an, and output it divided by the value of the remainder of the given natural number p.
Input
Consists of four rows.
The first line is a natural number k.
The second line contains K natural number B1, B2,..., bk.
The third line contains K natural number c1, C2,..., ck.
Line four contains three natural numbers m, N, p.
Output
Contains only one row: A positive integer that represents the value of mod p (am + am+1 + am+2 + ... + an).
Sample Input
2
1 1
1 1
2 10 1000003
Sample Output
142
HINT
For 100% of test data:
1<= k<=15
1 <= m <= N <= 1018
Source
Moment multiplication + fast power
The paragraph and the formula as two prefixes and subtraction can be multiplied by the moment.
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define LL Long Long#define MAXNusing namespace STD;intK LL b[ -],c[ -]; LL m,n,p; LL ans;structmatrix{LL A[MAXN][MAXN]; Matrix () {memsetA0,sizeof(a)); }friendMatrixoperator* (Matrix A,matrix B) {matrix ret; for(intI=1; i<=k+1; i++) for(intj=1; j<=k+1; j + +) for(intk=1; k<=k+1; k++) ret.a[i][j]= (ret.a[i][j]+a.a[i][k]*b.a[k][j])%p;returnRet }friendMatrixoperator^ (Matrix X,ll k) {matrix ret; for(intI=1; i<=k+1; i++) ret.a[i][i]=1; for(LL i=k;i;i>>=1, x=x*x) {if(i&1) ret=ret*x; }returnRet }}TMP1,TMP2; ll solve (ll x) {if(!x)returntmp2.a[1][k+1]; Matrix t=tmp1^x; T=tmp2*t;returnt.a[1][k+1];}intMain () {scanf("%d", &k); for(intI=1; i<=k;i++)scanf("%lld", &b[i]); for(intI=1; i<=k;i++)scanf("%lld", &c[i]);scanf("%lld%lld%lld", &m,&n,&p); for(intI=1; i<=k;i++) b[i]%=p,c[i]%=p,b[k+1]+=b[i],b[k+1]%=p; for(intI=1; i<=k;i++) tmp1.a[i][1]=tmp1.a[i][k+1]=c[i]; for(intI=2; i<=k;i++) tmp1.a[i-1][i]=1; tmp1.a[k+1][k+1]=1; for(intI=1; i<=k;i++) tmp2.a[1][i]=b[k-i+1]; tmp2.a[1][k+1]=b[k+1];if(n<=k) { for(inti=m;i<=n;i++) ans+=b[i],ans%=p;printf("%lld\n", ans);return 0; } ans=solve (N-k);if(m<=k) for(intI=1; i<m;i++) Ans-=b[i];ElseAns-=solve (m-k-1); Ans= (ans+p)%p;cout<<ans<<endl;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"SDOI2008" "BZOJ3231" recursive series