2017多校训练第二场 hdu6050 Funny Function(数学+快速幂+逆元)
来源:互联网 发布:java正则表达式$ 编辑:程序博客网 时间:2024/05/20 06:28
2017多校训练第二场 hdu6050 Funny Function(数学+快速幂+逆元)
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
Problem Description
Function Fx,y satisfies:
For given integers N and M,calculate
Fm,1 modulo 1e9+7.
Input
There is one integer T in the first line.
The next T lines,each line includes two integers N and M .
1<=T<=10000,1<=N,M<2^63.
Output
For each given N and M,print the answer in a single line.
Sample Input
2
2 2
3 3
Sample Output
2
33
样例理解:
2(T)个测试数据,每个数据给你2(N),2(M),求出Fm1的值,计算方法如图。
那么我们可以按照题目意思列出以下表格:
当N=2,M=2时:
F11=1 F12=1
F21=(F11+F12)=2
所以第一组测试样例的值为F21=2
当N=3,M=3时:
F11=1 F12=1 F13=3 F14=5 F15=11
F21=(F11+F12+F13)=5 F22=(F12+F13+F14)=9 F23=(F13+F14+F15)=19
F31=(F21+F22+F23)=33
所以第一组测试样例的值为F31=33
分析:这道题可以直接用矩阵快速幂做,不过公式也是很好推导的。
根据高中数学里有关数列的知识,
题目中所给式子 F1i=F1i-1+2*F1i-2,
可以化成 F1j-2*F1j-1=F1j-1-2*F1j-2
那么可以计算出F1j的通向公式:F1j=1/3*(2^n-(-1)^n)
计算出这个通项公式以后,我们可以把数列F分成2^n和(-1)^n两个部分,1/3可以最后再处理
那么F1就变成了这样的:
2^1 2^2 2^3 2^4… -1 1 -1 1 -1 1
而F21是F11前N项求和,利用等比数列求和公式,得到F21=(2^n-1)*2
而我们发现,F22是从F12开始的N项求和,它的每一项F1i都是F1i-1的两倍,所以F22是F21的两倍,以此类推,我们可以把F2n的左边写出来:
(2^n-1)2 (2^n-1)(2^2) (2^n-1)*(2^3) …
而F2n的右边的值取决于N的值,我们发现当N为偶数时右边的和为0,N为奇数时右边的和为-1
所以F2n的右边如下,且当M>=2时,它没有变化:
-1 0 -1 0 -1 0 -1 0…
往下推F3n的时候,我们发现,F2的左边又是一个等比数列,
用等比数列求和公式发现F31=(2^n-1)^2*2
,我们发现F31比F21多了一个(2^n-1),F21比F1多了一个(2^n-1),而且这个是不断递增下去的
那么第M行,F的左边应该是(2^n-1)^(M-1)*2,当N为奇数的时候,别忘了再+1(即-(-1)),还有之前先放下的系数1/3,就得到了最后的通项公式:
Fm1=1/3*(2^n-1)^(M-1)*2 (当N是偶数)
1/3*[(2^n-1)^(M-1)*2+1] (当N是奇数)
实现技巧:由于N,M的范围非常大(2^63),所以我们采用快速幂的办法迅速算出a^b,还有一个要注意的点是1/3这个系数,在mod1e9+7的情况下是不可以直接把答案除3的,应该乘以3关于1e9+7的逆元(此处等于333333336是我们为了节约时间提前算好的),我和队友当时直接除了3,导致WA了一次,还是很可惜
AC代码:
#include <iostream>#include <stdio.h>#include <algorithm>#include <iomanip>#include <vector>#include <queue>#include <map>#include <cstring>#include <string>#include <cctype>#include <cmath>typedef long long LL;using namespace std;const LL modd=1e9+7;LL niyuan = 333333336;//快速幂模板LL quickmod(LL a,LL b){ LL ans = 1; while(b) //用一个循环从右到左便利b的所有二进制位 { if(b&1) //判断此时b[i]的二进制位是否为1 { ans = (ans*a)%modd; //乘到结果上,这里a是a^(2^i)%m b--; //把该为变0 } b/=2; a = a*a%modd; } return ans;}int main(){ int cas; LL N,M; cin >> cas; while(cas--) { cin >> N >> M; LL res = quickmod(2,N) - 1; M--; res = quickmod(res,M) * 2 % modd; if(N % 2 == 1) res += 1; res= res * niyuan % modd; cout << res<< endl; } return 0;}
- 2017多校训练第二场 hdu6050 Funny Function(数学+快速幂+逆元)
- 2017多校训练Contest2: 1006 Funny Function hdu6050
- 2017 多校训练第二场 HDU 6050 Funny Function
- 2017杭电多校联赛第二场-Funny Function (hdu6050)快速幂解数学方程
- Hdu6050 Funny Function(2017多校第2场)
- HDU6050 Funny Function[矩阵快速幂]
- HDU-2017 多校训练赛2-1006-Funny Function
- (2017多校训练第二场)HDU
- (2017多校训练第二场)HDU
- (2017多校训练第二场)HDU
- (2017多校训练第二场)HDU
- (2017多校训练第二场)HDU
- hdu6050 Funny Function【打表+找规律+矩阵快速幂】
- Funny Function————(hdu6050)矩阵快速幂
- 2017 多校训练第一场 HDU 6038 Function
- 2017多校联合第二场 1006题 hdu 6050 Funny Function 递推公式 / 矩阵快速幂
- HDU6050-Funny Function
- HDU6050-Funny Function
- mysql的慢查询
- 数据库DML语句insert
- 多线程之不共享数据和共享数据
- SpringMVC RESTful风格CURD并集成Swagger2
- JavaWeb使用SpringMVC的简单案例
- 2017多校训练第二场 hdu6050 Funny Function(数学+快速幂+逆元)
- sql语句给数据库减肥,下面以网狐6603源码搭建为案例
- linux 调度总结
- 利用URLClassLoader读取Jar包并反射类(利用Tomcat源码)
- java分布式服务框架Dubbo的介绍与使用
- UVA 11817 Tunnelling the Earth
- Balala Power!
- Java_基础—标准输入输出流概述和输出语句
- fmpeg 时间戳问题汇总