51nod 1544 变系数非波那契
来源:互联网 发布:120首网络音乐产品 编辑:程序博客网 时间:2024/05/18 09:05
51nod 1544 变系数非波那契
原题链接https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1544
递推系数不是常数的一个递推
F(n)=F(n−1)S(n−1)+F(n−2)S(n−2)
有两种方法。
方法1:
根据递推关系。不断拆分。最终一定会得到一个类似于:
F(n)=F(0)A(n)+F(1)B(n)
S 是周期函数。(有bug的周期函数。。哈哈会扰动一下)
通过将F(0)=1,F(1)=0 和F(0)=0,F(1)=1 计算不同的系数。
数组A[],B[] 的贡献是可以累加的
并且有递推:
A[n]=S(n−1)A[n−1]+S(n−2)A[n−2]B[n]=S(n−1)B[n−1]+S(n−2)B[n−2]
整数周期矩阵快速幂。小周期利用A[],B[] 计算
需要跳过周期中的某个数的时候。可以用倍增计算。
比如预处理:
A[k][i],表示F[i]对F[i+2k]贡献的系数
B[k][i],表示F[i+1]对F[i+2k]贡献的系数
令F[i]=1,F[i+1]=0 带入A[k−1][] 计算得:
F[i+2k−1]=A[k−1][i]F[i]+B[k−1][i]F[i+1]=A[k−1][i]
同理:
F[i+2k−1+1]=A[k−1][i+1]
所以:
A[k][i]=F[i+2k]F[i+2k]=A[k−1][i+2k−1]F[i+2k−1]+B[k−1][i+2k−1]F[i+2k−1+1]
同理B[][] 也可以类似的 方法计算。
对于整数周期可以快速幂:
这种方法不是很好。因为编程不够方便。。倒不如直接全部使用矩阵维护。(因为中间还是需要矩阵)
方法2:
由Fn=Fn−1Sn−1+Fn−2Sn−2
得:[Sn−11Sn−20][Fn−1Fn−2]=[FnFn−1]
[Sn−11Sn−20]....[S21S10][S11S00][F1F0]=[FnFn−1]
S 存在周期 。使用线段树维护矩阵序列。配合快速幂。
下面是代码:
#include <stdio.h>#include <algorithm>#include <string.h>#define MAXN 50005using namespace std;typedef long long LL;LL P;LL s[MAXN];struct mat{ LL A[2][2]; mat() { memset(A,0,sizeof A); } mat(LL a,LL b) { A[1][0]=1; A[1][1]=0; A[0][0]=a; A[0][1]=b; } void e()//单位化 { A[0][0]=A[1][1]=1; A[0][1]=A[1][0]=0; } void clear() { memset(A,0,sizeof A); } mat operator *(const mat &a)const { mat b; for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) { b.A[i][j]+=(A[i][k]*a.A[k][j])%P; if(b.A[i][j]>=P)b.A[i][j]-=P; } return b; }};struct point{ LL j,v; point() { j=0; v=0; } bool operator <(const point a)const { return j<a.j; }}D[MAXN];struct node{ int c[2]; mat key; node() { c[0]=c[1]=0; key.e(); }};struct Bt{ node A[MAXN*2+1000]; int deep; int n; int root; mat ans; Bt() { deep=2; root=1; } void _insert(int x,int L,int R,const mat &key,int &k) { if(x<L||x>R)return ; if(!k)k=deep++; if(L==R) { A[k].key=key; return; } int mid=(L+R)>>1; _insert(x,L,mid,key,A[k].c[0]); _insert(x,mid+1,R,key,A[k].c[1]); A[k].key=A[A[k].c[1]].key*A[A[k].c[0]].key; } void insert(int x,const mat &key) { _insert(x,0,n,key,root); } void _query(int l,int r,int L,int R,int k) { if(R<l||L>r)return ; if(l<=L&&R<=r) { ans=A[k].key*ans; return; } int mid=(L+R)>>1; _query(l,r,L,mid,A[k].c[0]); _query(l,r,mid+1,R,A[k].c[1]); } mat query(int l,int r) { ans.e(); _query(l,r,0,n,root); return ans; }}T;int n,m;mat RE;mat Pow(mat a,LL b){ mat tmp; tmp.e(); while(b) { if(b&1) tmp=tmp*a; a=a*a; b>>=1; } return tmp;}mat slove(LL L,LL R){ mat ans; ans.e(); if(R<L) return ans; if(L/n==R/n) return T.query(L%n,R%n); LL u=L+n-L%n; LL d=R-R%n; ans=Pow(RE,(d-u)/n); ans=ans*T.query(L%n,n-1); ans=T.query(0,R%n)*ans; return ans;}int main (){ LL k; scanf("%lld %lld",&k,&P); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",s+i); scanf("%d",&m); for(int i=0;i<m;i++) scanf("%lld %lld",&D[i].j,&D[i].v); if(k==0) { printf("0\n"); return 0; } sort(D,D+m); T.n=n-1; for(int i=1;i<n;i++) T.insert(i,mat(s[i],s[i-1])); T.insert(0,mat(s[0],s[n-1])); RE=T.query(0,n-1); LL L=1; mat ans; ans.e(); for(int i=0;i<m&&L<k;i++) { LL lim=min(k-1,D[i].j-1); ans=slove(L,lim)*ans; L=lim+1; if(L==k)break; int t=i+1; while(D[t].j==D[t-1].j+1&&t<m)t++; ans= mat(D[i].v,s[(D[i].j-1+n)%n]) * ans; L++; for(i++;i<t&&L<k;i++,L++) ans=mat(D[i].v,D[i-1].v)*ans; if(L==k)break; ans= mat(s[L%n],D[i-1].v) * ans; L++; if(L==k)break; i--; } ans=slove(L,k-1)*ans; printf("%lld\n",ans.A[0][0]); return 0;}
阅读全文
1 0
- 51nod 1544 变系数非波那契
- 51nod 1628 非波那契树 (倍增)
- 51nod 1358 浮波那契
- 51nod 1358 浮波那契
- 51nod-1358:浮波那契
- 51nod 1358 浮波那契
- 读书笔记: 变系数波方程
- 51nod 1358:浮波那契 构造矩阵
- 51Nod 1358 浮波那契 (矩阵快速幂)
- 51nod 1070 斐波那契博弈
- 51Nod-1350-斐波那契表示
- 51Nod-1358-浮波那契
- 51nod 1350 斐波那契表示
- 51nod-斐波那契表示(找规律)
- 51nod-1358-浮波那契(构造矩阵)
- 51nod-1350:斐波那契表示
- 51nod-1350 斐波那契表示(规律)
- 51nod 1355 斐波那契的最小公倍数
- Java常见面试(11)
- 九天学会Java,第五天,函数定义函数调用
- spark集群搭建与集群上运行wordcount程序
- 拉格朗日对偶性
- 11、TCP:传输控制协议
- 51nod 1544 变系数非波那契
- 让Hive支持行级insert、update、delete
- Android permission权限与安全机制解析(下)PACKAGE_USAGE_STATS以及悬浮窗
- DB2中如何根据锁名找到对应的行
- HDU
- bfs和dfs搜索总结
- Linux下MySQL中文乱码问题解决方案
- 隐马尔可夫模型的介绍(一)
- ubuntu server 16.04的安装 以及配置网络还有ssh服务