-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathlinear_rec.cpp
30 lines (30 loc) · 950 Bytes
/
linear_rec.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//init O(n^2log) query(n^2 logk)
//input: terms: first n term; trans: transition function; MOD; LOG=mxlog of k
//output calc(k): kth term mod MOD
//example: {1,1} {2,1} an=2*a_(n-1)+a_(n-2); calc(3)=3 calc(10007)=71480733
struct LinearRec{
typedef vector<int> vi;
int n; vi terms, trans; vector<vi> bin;
vi add(vi &a, vi &b){
vi res(n*2+1);
fore(i,0,n+1)fore(j,0,n+1)res[i+j]=(res[i+j]*1LL+(ll)a[i]*b[j])%MOD;
for(int i=2*n; i>n; --i){
fore(j,0,n)res[i-1-j]=(res[i-1-j]*1LL+(ll)res[i]*trans[j])%MOD;
res[i]=0;
}
res.erase(res.begin()+n+1,res.end());
return res;
}
LinearRec(vi &terms, vi &trans):terms(terms),trans(trans){
n=SZ(trans);vi a(n+1);a[1]=1;
bin.pb(a);
fore(i,1,LOG)bin.pb(add(bin[i-1],bin[i-1]));
}
int calc(int k){
vi a(n+1);a[0]=1;
fore(i,0,LOG)if((k>>i)&1)a=add(a,bin[i]);
int ret=0;
fore(i,0,n)ret=((ll)ret+(ll)a[i+1]*terms[i])%MOD;
return ret;
}
};