[zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)
Power of Fibonacci
Time Limit: 5 Seconds Memory Limit: 65536 KB
In mathematics, Fibonacci numbers or Fibonacci series or Fibonacci sequence are the numbers of the following integer sequence:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...
By definition, the first two numbers in the Fibonacci sequence are 1 and 1, and each subsequent number is the sum of the previous two. In mathematical terms, the sequence Fn of
Fibonacci numbers is defined by the recurrence relation Fn = Fn - 1 + Fn - 2 with seed values F1 = 1 and F2 = 1.
And your task is to find ΣFiK, the sum of the K-th power of the first N terms in the Fibonacci sequence. Because the answer can
be very large, you should output the remainder of the answer divided by 1000000009.
Input
There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:
There are two integers N and K (0 <= N <= 1018, 1 <= K <= 100000).
Output
For each test case, output the remainder of the answer divided by 1000000009.
Sample Input
5
10 1
4 20
20 2
9999 99
987654321987654321 98765
Sample Output
143
487832952
74049690
113297124
108672406
Hint
The first test case, 1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 + 34 + 55 = 143.
The second test case, 120 + 120 + 220 + 320 =3487832979, and 3487832979 = 3 * 1000000009 + 487832952, so the output is 487832952.
题目大意
非常明白,求菲波那契数列每一个数的m次方的前n项和。
思路
当时看到m的取值范围就没敢在往下写。直到cf 255(446 C)有一道类似思路的线段树,官方的editorial里面给出了一个解释,就是求其二次剩余,然后该数列能够用幂差来表示。
(二次剩余求解)
(以上三个式子均用拓展欧几里得推出。将sqrt5作为一个总体进行逆元求解)
(于是带入后我们就看到了一个剩余系的式子)
为什么要这么做的原因可能就和逆元的原理有些类似了,由于我们直到结果是整数,所以每一步都能在剩余系之中找到一个整数的运算取代了。
接下来就设
于是随意一个数的m次方为
对二项式展开之后其前n项求和
枚举k来求和就可以
对于中间的一项等比数列的求和来加速。否则仍会超时。
求二次剩余以及各项系数值的code:(因为二次剩余大多有两个不同根。所以结果不同未必影响计算结果)
模板来自:blog.csdn.net/acdreamers/article/details/10182281
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 1000000009
using namespace std;
long long sqrt5,s,r1,r2;
long long ts,w;
struct D{
long long p,d;
};
void egcd(long long a,long long b,long long &x,long long &y)
{
if (b==0)
{
x=1;
y=0;
return;
}
egcd(b,a%b,x,y);
int t=x;
x=y,y=t-a/b*y;
return;
}
long long mypow(long long x,long long y,long long p)
{
long long res=1,mul=x;
while (y)
{
if (y & 1)
res=res * mul % p;
mul=mul * mul % p;
y/=2;
}
return res;
}
D mul(D a,D b,long long m)
{
D ans;
ans.p=(a.p * b.p % m +a.d * b.d %m *w % m)%m;
ans.d=(a.p * b.d % m +a.d * b.p% m)%m;
return ans;
}
D power(D a,long long b,long long m)
{
D ans;
ans.p = 1;
ans.d = 0;
while (b)
{
if (b & 1)
{
ans=mul(ans,a,m);
}
b/=2;
a=mul(a,a,m);
}
return ans;
}
long long sqre(long long x,long long y)
{
if (y==2) return 1;
if (mypow(x,(y-1)>>1,y)+1 == y)
return -1;
long long a,t;
for (a=1;a<y;a++)
{
t= a * a - x;
w= (t + y) % y;
if (mypow(w,(y-1)>>1,y)+1 == y) break;
}
D tmp;
tmp.p=a;
tmp.d=1;
D ans = power(tmp,(y+1)>>1,y);
return ans.p;
}
int main()
{
sqrt5=sqre(5,mod);
printf("%I64d\n",sqrt5);
long long x,y;
egcd(5,mod,x,y);
x=(x+mod)%mod;
s=(sqrt5*x)%mod;
printf("%I64d\n",s); egcd(2,mod,x,y);
x=(x+mod)%mod;
r1=((sqrt5+1)*x)%mod;
r2=((-sqrt5+1+mod)*x)%mod; printf("%I64d\n",r1);
printf("%I64d\n",r2);
int T;
return 0;
}
系数带入后本题的代码
#include <cstdio>
#include <cstring>
#include <algorithm>
long long s=723398404,r1=308495997,r2=691504013;
long long mod=1000000009;
long long c[100005];
typedef long long Ma[2][2];
void egcd(long long a,long long b,long long &x,long long &y)
{
if (b==0)
{
x=1;
y=0;
return;
}
egcd(b,a%b,x,y);
int t=x;
x=y,y=t-a/b*y;
return;
}
long long mypow(long long x,long long y)
{
long long res=1;
while (y)
{
if (y%2)
res=res * x % mod;
x=x * x % mod;
y/=2;
}
return res;
}
long long acce(long long x,long long y)//等比数列高速求和
{
long long ans=0;
long long powe=x;
long long sum=x;
long long mul=1;
while (y)
{
if (y&1)
{
ans+=mul*sum;
ans%=mod;
mul*=powe;
mul%=mod;
}
sum*=(powe+1);
sum%=mod;
powe*=powe;
powe%=mod;
y/=2;
}
return ans;
}
int main()
{
int T;
long long n,m;
scanf("%d",&T);
while (T--)
{
long long ans=0;
scanf("%lld%lld",&n,&m);
c[0]=1;
long long x,y;
for (long long i=1;i<=m;i++)
{
egcd(i,mod,x,y);
x=(x+mod)%mod;
c[i]=(c[i-1]*x)%mod;
c[i]=(c[i]*(m-i+1))%mod;
}
for (long long i=0;i<=m;i++)
{
x=c[i];
x=x * acce(mypow(r1,i)*mypow(r2,m-i)%mod,n)%mod;
x=(x+mod)%mod;
if ((m-i)%2)
ans=(ans - x + mod)%mod;
else
ans=(ans + x + mod)%mod;
}
ans=ans*mypow(s,m)%mod;
printf("%lld\n",ans);
}
system("pause");
return 0;
}
[zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)的更多相关文章
- 51 Nod 1256 乘法逆元(数论:拓展欧几里得)
1256 乘法逆元 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K ...
- ZOJ Problem Set - 3593 拓展欧几里得 数学
ZOJ Problem Set - 3593 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3593 One Person ...
- ACM数论-欧几里得与拓展欧几里得
ACM数论——欧几里得与拓展欧几里得 欧几里得算法: 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd ...
- BZOJ-2242 计算器 快速幂+拓展欧几里得+BSGS(数论三合一)
污污污污 2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2312 Solved: 917 [Submit][S ...
- SGU 141.Jumping Joe 数论,拓展欧几里得,二元不等式 难度:3
141. Jumping Joe time limit per test: 0.25 sec. memory limit per test: 4096 KB Joe is a frog who lik ...
- poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】
POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...
- NOIP2012拓展欧几里得
拉板题,,,不说话 我之前是不是说过数据结构很烦,,,我想收回,,,今天开始的数论还要恶心,一早上听得头都晕了 先来一发欧几里得拓展裸 #include <cstdio> void gcd ...
- poj 1061 青蛙的约会+拓展欧几里得+题解
青蛙的约会+拓展欧几里得+题解 纵有疾风起 题意 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出 ...
- poj 1061 青蛙的约会 拓展欧几里得模板
// poj 1061 青蛙的约会 拓展欧几里得模板 // 注意进行exgcd时,保证a,b是正数,最后的答案如果是负数,要加上一个膜 #include <cstdio> #include ...
随机推荐
- linux系统怎么改为中文版(转)
linux系统安装好后怎么改为中文版呢?今天就跟大家介绍下linux系统改为中文版的方法,希望能帮助到大家! 以下是linux系统改为中文版的四种方法,一起来看看: 方法1:写入环境变量 echo & ...
- 必学100个常用linux命令大全
1,echo “aa” > test.txt 和 echo “bb” >> test.txt //>将原文件清空,并且内容写入到文件中,>>将内容放到文件的尾部 2 ...
- 【BZOJ 1088 扫雷Mine】模拟
http://www.lydsy.com/JudgeOnline/problem.php?id=1088 2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目. 第一列的 ...
- 【HDU 4771 Stealing Harry Potter's Precious】BFS+状压
2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点, ...
- CentOS7 yum lamp 虚拟主机配置 lamp各组件简单影响性能的参数调整--for 一定的环境需求
LAMP Server on CentOS 7 Updated Tuesday, January 13, 2015 by Joel Kruger This guide provides step-by ...
- OMNeT++安装教程
前提及注意事项: 1) 安装之前首先要确定已经安装好GCC编译环境(例如:MinGW.Cygwin,选择一种安装); (否则OMNeT++会安装不成功),具体安装教程详见另一篇文章 MinGW安装教程 ...
- U盘量产的作用
优盘量产:字面意思就是,批量生产优盘.是指批量对U盘主控芯片改写数据,如,写生产厂商信息.格式化等.而用来对U盘完成该操作的软件程序,顾名思义就是U盘量产工具. U盘量产的作用: 电脑正确识别 ...
- 【UNIX网络编程(二)】基本TCP套接字编程函数
基于TCP客户/server程序的套接字函数图例如以下: 运行网络I/O.一个进程必须做的第一件事就是调用socket函数.指定期望的通信协议类型. #include <sys/socket.h ...
- 通过设置cookie实现单点登录
最近要做个登录一个客户端跳转到另一个网站不用再登录,有两种方法,第一种就是写接口通过客户端传值账号直接到目标网站,另一种是写入cookie到目标网站.由于目标网站之前就是通过cookie实现单点登录, ...
- java调用Command命令
----------- import java.io.BufferedReader; import java.io.InputStreamReader; /** * 此类用来执行Command命令 * ...