Fibonacci数列的幂和 zoj 3774
题目大意:
求斐波那契数列前n项的k次幂和 Mod 1000000009。 n<=1e18, k<=1e5
这题的k比较大,所以不能用矩阵乘法来递推。学到了新姿势... http://blog.csdn.net/acdreamers/article/details/23039571
基本思想就是求出通项公式,把里面的$\sqrt{5}$ 用 $x$ 代替, 其中 $x^2\equiv 5\pmod{1000000009}$
然后二项式展开求和就好了。
一个合法的$x$是383008016。 正好前几天做了个高次剩余方程的题,直接拉过去跑出来。。
为什么这样替代是合法的呢? 网络上好像没找到严谨的证明。
下面给出我个人的不严谨证明:
将原式子合并之后最终会得到$\frac{P(t)}{Q(t)}$ 这样的形式。 其中$t=\sqrt{5}$ $P(t)$和$Q(t)$是关于$t$的多项式.
把$P(t)$ $Q(t)$中次数>=2的可以利用$t^2=5$降幂成次数不超过1的, 最后变成$\frac{P'(t)}{Q'(t)}$ 这样的形式.
由于最终答案一定是整数,所以 $Q'(t)$ 能整除 $P'(t)$ 。 设 $\frac{P'(t)}{Q'(t)}=K$
那么把$t$ 换成 上面求出的 $x$ 得到的 $\frac{P'(x)}{Q'(x)}$ 也是 $K$. 不影响答案。
AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdlib>
#include <set>
#include <queue>
using namespace std; #define X first
#define Y second
#define Mod 1000000009
#define N 100010
#define M 101 typedef long long ll; const int INF=<<;
const int sqrt5=;
int P,Q;
int fac[N],fac_inv[N]; int Power(int x,ll p)
{
int res=;
for (;p;p>>=)
{
if (p&) res=1ll*res*x%Mod;
x=1ll*x*x%Mod;
}
return res;
} int C(int n,int m)
{
if (m==) return ;
int res=1ll*fac[n]*fac_inv[m]%Mod;
return 1ll*res*fac_inv[n-m]%Mod;
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); P=1ll*(+sqrt5)*Power(,Mod-)%Mod;
Q=1ll*(-sqrt5)*Power(,Mod-)%Mod;
if (Q<) Q+=Mod;
fac[]=fac_inv[]=;
for (int i=;i<N;i++) fac[i]=1ll*fac[i-]*i%Mod,fac_inv[i]=Power(fac[i],Mod-);
int T,K,ans; ll n;
scanf("%d",&T);
while (T--)
{
scanf("%lld%d",&n,&K);
ans=;
for (int i=K,op=;i>=;i--,op=-op)
{
int tmp1=op*C(K,i),tmp2,x=1ll*Power(P,i)*Power(Q,K-i)%Mod;
if (x==) tmp2=n%Mod;
else tmp2=1ll*x*(Power(x,n)-)%Mod,tmp2=1ll*tmp2*Power(x-,Mod-)%Mod;
ans+=1ll*tmp1*tmp2%Mod;
ans%=Mod;
}
if (ans<) ans+=Mod;
ans=1ll*ans*Power(Power(sqrt5,Mod-),K)%Mod;
printf("%d\n",ans);
}
return ;
}
我的求高次剩余方程的代码(目前只会做模数是质数的情况...):
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1038
#include <cstdio>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std; #define X first
#define Y second
#define N 100010
#define M 5783
typedef long long ll;
typedef unsigned long long ull; const int Mod=; int prime[N];
bool flag[N];
vector<int> ans; int Power(int x,int p,int Mod)
{
int res=;
for (;p;p>>=)
{
if (p&) res=1ll*res*x%Mod;
x=1ll*x*x%Mod;
}
return res;
} bool Check(int g,int P,int a[])
{
for (int i=;i<=a[];i++) if (Power(g,(P-)/a[i],P)==) return false;
return true;
} int Find_Root(int P)
{
int x=P-,a[]; a[]=;
for (int i=;i<=prime[] && prime[i]*prime[i]<=x;i++)
{
if (x%prime[i]==)
{
a[++a[]]=prime[i];
while (x%prime[i]==) x/=prime[i];
}
}
if (x!=) a[++a[]]=x;
for (int i=;;i++) if (Check(i,P,a)) return i;
} vector<pair<int,int> > hash[M]; int Calc_Exp(int a,int b,int P) // 求解a^x=b (mod P)
{
int m=ceil(sqrt(P+0.5));
for (int i=;i<M;i++) hash[i].clear(); int v=Power(a,m,P),tmp=; v=Power(v,P-,P);
hash[].push_back(make_pair(,));
for (int i=;i<m;i++)
{
tmp=1ll*tmp*a%P;
hash[tmp%M].push_back(make_pair(tmp,i));
} for (int i=;i<m;i++)
{
int t=b%M;
for (int j=;j<hash[t].size();j++)
{
if (hash[t][j].X==b) return i*m+hash[t][j].Y;
}
b=1ll*b*v%P;
}
} void ex_gcd(ll a,ll b,ll &x,ll &y,ll &d)
{
if (!b)
{
d=a;
x=;
y=;
}
else
{
ex_gcd(b,a%b,y,x,d);
y-=a/b*x;
}
} //X^A = B (mod P)
void Solve_Equation(int A,int B,int P)
{
ans.clear();
int g=Find_Root(P); //求出P的原根
int b=Calc_Exp(g,B,P); // B=g^b
ll x,y,d;
ex_gcd(A,P-,x,y,d);
if (b%d==)
{
int del=(P-)/d,tmp,t;
x*=b/d;
x%=del;
if (x<) x+=del;
tmp=Power(g,(int)x,P);
t=Power(g,del,P);
while (x<=P-) ans.push_back(tmp),x+=del,tmp=1ll*tmp*t%P;
sort(ans.begin(),ans.end());
for (int i=;i<ans.size();i++) printf("%d%c",ans[i],i==ans.size()-? '\n':' ');
}
if (ans.size()==) printf("No Solution\n");
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout); for (int i=;i<N;i++)
{
if (!flag[i]) prime[++prime[]]=i;
for (int j=;j<=prime[] && i*prime[j]<N;j++)
{
flag[i*prime[j]]=true;
if (i%prime[j]==) break;
}
} int T,A,B,P; scanf("%d",&T);
while (T--)
{
scanf("%d%d%d",&P,&A,&B);
Solve_Equation(A,B,P);
} return ;
}
可以扩展到模数不是质数的情况,等我学会了在写篇文章 记录具体做法吧。
Fibonacci数列的幂和 zoj 3774的更多相关文章
- ACM学习历程—HDU 5451 Best Solver(Fibonacci数列 && 快速幂)(2015沈阳网赛1002题)
Problem Description The so-called best problem solver can easily solve this problem, with his/her ch ...
- 矩阵乘法快速幂 codevs 1732 Fibonacci数列 2
1732 Fibonacci数列 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在“ ...
- 算法设计与分析 1.2 不一样的fibonacci数列 (矩阵快速幂思想)
题目描述 Winder 最近在学习 fibonacci 数列的相关知识.我们都知道 fibonacci 数列的递推公式是F(n) = F(n - 1) + F(n - 2)(n >= 2 且 n ...
- 矩阵乘法快速幂 codevs 1250 Fibonacci数列
codevs 1250 Fibonacci数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 定义:f0=f1=1 ...
- 1250 Fibonacci数列(矩阵乘法快速幂)
1250 Fibonacci数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 定义:f0=f1=1, f ...
- fibonacci 数列及其应用
fibonacci 数列及其延展 fibonacci计算 fibonacci数列是指 0,1,1,2,3,5,8,13,21……这样自然数序列,即从第3项开始满足f(n)=f(n-1)+f(n-2): ...
- 【wikioi】1250 Fibonacci数列(矩阵乘法)
http://wikioi.com/problem/1250/ 我就不说这题有多水了. 0 1 1 1 矩阵快速幂 #include <cstdio> #include <cstri ...
- 【蓝桥杯】入门训练 Fibonacci数列
入门训练 Fibonacci数列 时间限制:1.0s 内存限制:256.0MB 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. ...
- hdu 5895 广义Fibonacci数列
Mathematician QSC Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
随机推荐
- 基于jquery类库的绘制二维码的插件jquery.qrcode.js
jquery.qrcode.min.js 如下 (function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.d ...
- oracle数据库修改编码
(1)SYSTEM 用户登录SQLPLUS SYS是sysdba用户,不能直接登录 (2)SYSDBA登录 CONN / as sysdba; (3)查看数据库字符集 ...
- Python3环境安装Scrapy爬虫框架过程及常见错误
收录待用,修改转载已取得腾讯云授权 Scrapy安装介绍 Scrapy的安装有多种方式,它支持Python2.7版本及以上或Python3.3版本及以上.下面说明Python3环境下的安装过程. Sc ...
- 【千纸诗书】—— PHP/MySQL二手书网站后台开发之功能实现
前言:前一篇温习了网站开发需要掌握的基础知识,这一篇重点梳理一下各个功能模块的[详细设计与实现].项目github地址:https://github.com/66Web/php_book_store, ...
- 深入理解C/C++ [Deep C (and C++)] (2)
好.接着深入理解C/C++之旅.我在翻译第一篇的时候.自己是学到不不少东西,因此打算将这整个ppt翻译完成. 请看以下的代码片段: #include <stdio.h> void foo( ...
- 【Python 数据分析】Numpy模块
Numpy模块可以高效的处理数据,提供数组支持.很多模块都依赖他,比如:pandas.scipy.matplotlib 安装Numpy 首先到网站:https://www.lfd.uci.edu/~g ...
- 《深入浅出mfc》 第1章 笔记
需要什么函数库(.lib) windows支持动态链接库,应用程序所调用 的windows api 函数是在“执行期间“才链接上的.Windows程序调用 可以分为 C Runtimes以及windo ...
- ftp获取远程Pdf文件
此程序需要安装ftp服务器,安装adobe reader(我这里使用的adobe reader9.0) 1.部署ftp服务器 将ftp的权限设置为允许匿名访问,部署完成 2.安装adobe reade ...
- 异步编程C#回调方法
1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...
- 我也来谈谈使用Zen Coding快速开发html和css原理
zen coding 是一种仿css选择器的语法来快速开发html和css的开源项目.现已更名为Emmet.可以到github上下载拜读.在这个都想偷懒的世界里,此方法可以极大的缩短开发人员的开发时间 ...