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 ...
随机推荐
- system表空间爆满解决方法
分类: Oracle 问题描述: 对数据库做检查,发现system表空间持续占满99%.使用如下语句查看: SQL> select b.tablespace_name "表空间&q ...
- 关于 Delphi 中流的使用(2) 用 TFileStream(文件流) 读写
TStream 是一个抽象的基类, 不能直接生成对象. 在具体的应用中, 主要使用它的子孙类:TFileStream: 文件流TStringStream: 字符串流TMemoryStream: 内存流 ...
- fl2440字符设备led驱动
首先要明白字符设备驱动注册的基本流程 当我们调用insomd命令加载驱动后,驱动程序从module_init函数开始执行:硬件初始化 -> 申请主次设备号 -> 定义fops(file_o ...
- win7系统下ping不是内部或外部命令
win7下ping不是内部或外部命令,在使用java设置变量环境时,可能会遇到这样的问题,出现win7下ping不是内部或外部命令,是在设置变量环境是把一些设置删掉了的原因,请看在win7下怎么还原. ...
- Scala实现冒泡排序、归并排序和快速排序
1.冒泡排序 def sort(list: List[Int]): List[Int] = list match { case List() => List() case head :: tai ...
- shell报错:未预期的符号***附近有语法错误
1.安装dos2unix(我的centos命令: yum install dos2unix)2.执行命令:dos2unix 文件名.sh 3.执行命令:bash -n 文件名.sh (检查语法错 ...
- 使用zbar 解码二维码 条形码
#!/usr/bin/env python # coding: u8 import os import zbar import Image import urllib import uuid def ...
- js比较数字相等
示例代码: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...
- Centos6.2上做nginx和tomcat的集成及负载均衡(已实践)
Centos6.2上做nginx和tomcat的集成及负载均衡 ---------------------------------------------------------Jdk-------- ...
- 深入浅出理解之 onInterceptTouchEvent与onTouchEvent
参考:http://blog.csdn.net/android_tutor/article/details/7193090 与 http://www.cnblogs.com/kingcent/ ...