JZOJ 1240. Fibonacci sequence
来源:互联网 发布:防止sql注入的函数 编辑:程序博客网 时间:2024/05/21 07:10
原题
题解
对于80%的数据,根据递推式用
O(n) 的方法就可以了。对于100%的数据,显然要用到矩阵方法,这里介绍两种思路。
设
F(n),S(n) 分别为Fibonacci−sequence 的第n项和前n项和。求第x~y项的和相当于求
S(y)−S(x−1) 。于是问题变成了怎么求
S(y) 和S(x−1) 。出
S(n) 的通项,和F(n) 的通项比较。可以发现
S(n)=F(n+2)−1 ,于是就用矩阵乘法求出数列的第N+2 项。但这样的方法在比赛中不可取,因为,
f(n)=5√5[(1+5√2)n−(1−5√2)n] S(n)=5√5[(1+5√2)n+2−(1−5√2)n+2]−1 显然除非你的手算能力足够强,否则这需要浪费大量时间才能推倒出来。
当然,由于
S(n)=F(n+2)−1 规律还是优美的。善于观察的同写几项出来就可以发现规律.
根据
f(n)=f(n−1)+f(n−2),S(n)=S(n−1)+f(n) 我们可以按如下方法构造一个矩阵。
[f(n)f(n−1)S(n)]=[f(n−1)f(n−2)S(n−1)]∗⎡⎣⎢110100111⎤⎦⎥ 这种方法比较直观,对矩阵乘法比较熟悉的同学应该很容易想到.
Code
#include<cstdio>#include<cstring>using namespace std;int mid[2][2],s[2][2],c[2];int mid1[2][2],mid2[2][2];int ans1[2],ans2[2];const int mo=10000;inline int read(){ int data=0; char ch=0; while(ch<'0' || ch>'9') ch=getchar(); while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); return data;}//读入优化inline void ksm1(int v){ int ans[2][2]; ans[0][0]=ans[1][1]=1; ans[1][0]=ans[0][1]=0; while(v) { if(v%2) { memset(s,0,sizeof(s)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) s[i][j]=(s[i][j]+ans[i][k]*mid1[k][j])%mo; memcpy(ans,s,sizeof(ans)); } memset(s,0,sizeof(s)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) s[i][j]=(s[i][j]+mid1[i][k]*mid1[k][j])%mo; memcpy(mid1,s,sizeof(mid1)); v/=2; } memcpy(mid1,ans,sizeof(mid1));}//快速幂前x-1项inline void ksm2(int v){ int ans[2][2]; ans[0][0]=ans[1][1]=1; ans[1][0]=ans[0][1]=0; while(v) { int s[2][2]; if(v%2) { memset(s,0,sizeof(s)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) s[i][j]=(s[i][j]+ans[i][k]*mid2[k][j])%mo; memcpy(ans,s,sizeof(ans)); } memset(s,0,sizeof(s)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) s[i][j]=(s[i][j]+mid2[i][k]*mid2[k][j])%mo; memcpy(mid2,s,sizeof(mid2)); v/=2; } memcpy(mid2,ans,sizeof(mid2));}//快速幂前y项int main(){ mid[0][1]=mid[1][1]=mid[1][0]=1; int T=read(); while(T--) { int x=read(),y=read(); ans1[0]=ans1[1]=ans2[0]=ans2[1]=1; memcpy(mid1,mid,sizeof(mid1)); memcpy(mid2,mid,sizeof(mid2)); ksm1(x-1); ksm2(y); memset(c,0,sizeof(c)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) c[i]=(c[i]+ans1[j]*mid1[i][j])%mo; memcpy(ans1,c,sizeof(ans1)); memset(c,0,sizeof(c)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) c[i]=(c[i]+ans2[j]*mid2[i][j])%mo;//矩阵乘法 memcpy(ans2,c,sizeof(ans2)); printf("%d\n",(ans2[1]+mo-ans1[1])%mo);//相减得区间和 } return 0;}
1 1
- JZOJ 1240. Fibonacci sequence
- JZOJ.1240. Fibonacci sequence
- fibonacci sequence
- Fibonacci Sequence
- Fibonacci sequence
- Fibonacci sequence
- 【typical】【JZOJ 5296】Sequence
- SZ Fibonacci Sequence
- 1-2 Fibonacci sequence
- JZOJ1240. Fibonacci sequence
- Sicily 1779 Fibonacci Sequence Multiplication
- Fibonacci sequence of k order
- 斐波纳契数列(Fibonacci Sequence)
- A Problem With Fibonacci Sequence
- Sicily 1779. Fibonacci Sequence Multiplication
- LintCode算法题:Fibonacci Sequence
- ural 1133. Fibonacci Sequence math
- 【JZOJ 5296】【清华集训2017模拟】Sequence
- 放下过去,拥抱将来
- 第一章 Android开发简介和常见控件介绍
- 系统调用日志收集系统
- Eclipse Maven问题
- MySQL查看和修改数据库存储目录
- JZOJ 1240. Fibonacci sequence
- lstat()
- 个人学习-java-jdbc 数据库连接池
- meta标签中的http-equiv属性使用介绍
- spring2.5+hibernate基于xml配置的实例
- java初识类和对象
- windows服务程序编写
- C语言lstat()函数:由文件描述词取得文件状态
- LintCode_186 Max Points on a Line