bzoj5118 Fib数列2 二次剩余+矩阵快速幂
2024-09-01 10:53:04
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=5118
题解
这个题一看就是不可做的样子。
求斐波那契数列的第 \(n\) 项,\(n \leq 2^{10^{15}}\)???
这样人怎么矩阵快速幂啊。
等等这个模数很神奇啊。
\(1125899839733759\) 好像是一个质数,还以 \(9\) 结尾。
那么 \(5\) 对于 \(1125899839733759\) 一定有二次剩余咯。
那么根据 Fib 的通项公式
\[f(n) = (\frac{\sqrt 5+1}{2})^n + (\frac{\sqrt 5 - 1}2)^n
\]
\]
那么这个 \(2^n\) 就可以根据费马小定理就可以转化成 \(n \bmod P-1\) 了。
那么这个 \(2^n\) 的范围瞬间小了很多。
于是就可以直接矩阵快速幂了,注意乘法要用快速乘实现。
UPD: 发现好像傻掉了,都有通项公式了,还写什么矩阵快速幂。
时间复杂度 \(O(T\log^2 n)\)。
#include<bits/stdc++.h>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const ll P = 1125899839733759;
ll n;
inline void sadd(ll &x, ll y, const ll &P = ::P) { x += y; x >= P ? x -= P : x; }
inline ll smod(const ll &x, const ll &P = ::P) { return x >= P ? x - P : x; }
inline ll fmul(ll x, ll y, const ll &P = ::P) {
ll ans = 0;
for (; y; y >>= 1, sadd(x, x, P)) if (y & 1) sadd(ans, x, P);
return ans;
}
inline ll fpow(ll x, ll y, const ll &P = ::P) {
ll ans = 1;
for (; y; y >>= 1, x = fmul(x, x, P)) if (y & 1) ans = fmul(ans, x, P);
return ans;
}
struct Matrix {
ll a[2][2];
inline Matrix() { memset(a, 0, sizeof(a)); }
inline Matrix(const ull &x) {
memset(a, 0, sizeof(a));
a[0][0] = a[1][1] = x;
}
inline Matrix operator * (const Matrix &b) {
Matrix c;
c.a[0][0] = smod(fmul(a[0][0], b.a[0][0]) + fmul(a[0][1], b.a[1][0]));
c.a[0][1] = smod(fmul(a[0][0], b.a[0][1]) + fmul(a[0][1], b.a[1][1]));
c.a[1][0] = smod(fmul(a[1][0], b.a[0][0]) + fmul(a[1][1], b.a[1][0]));
c.a[1][1] = smod(fmul(a[1][0], b.a[0][1]) + fmul(a[1][1], b.a[1][1]));
return c;
}
} A, B;
inline Matrix fpow(Matrix x, ll y) {
Matrix ans(1);
for (; y; y >>= 1, x = x * x) if (y & 1) ans = ans * x;
return ans;
}
inline void work() {
A.a[0][0] = 1, A.a[0][1] = 1;
A.a[1][0] = 1, A.a[1][1] = 0;
B.a[0][0] = 0, B.a[1][0] = 1;
A = fpow(A, n) * B;
printf("%lld\n", A.a[0][0]);
}
inline void init() {
read(n);
n = fpow(2, n, P - 1);
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
int T;
read(T);
while (T--) {
init();
work();
}
fclose(stdin), fclose(stdout);
return 0;
}
最新文章
- Entity Framework 6 Recipes 2nd Edition(10-9)译 ->; 在多对多关系中为插入和删除使用存储过程
- MVC5+EF6+AutoMapper+Bootstrap打造在线博客(1.1)
- MySQL: Table &#39;mysql.plugin&#39; doesn&#39;t exist的解决
- 编写CLR存储过程中使用SqlDataRecord
- html5语法
- [ASP.NET]动态绑定树控件:
- URAL 1069 Prufer Code 优先队列
- js 函数闭包内部返回函数体调用方法难点解答
- ASP.NET对HTML元素进行权限控制(三)
- (转)Ubuntu 12.04 LTS 构建高可用分布式 MySQL 集群
- Java静态类
- 淘宝接口实现ip归属地查询
- VS注释快捷键
- 高性能JS(读书札记)
- 【java】之算法复杂度o(1), o(n), o(logn), o(nlogn)
- [pat]1068 Find More Coins
- io.netty.resolver.dns.DnsNameResolverContext
- 函数使用九:CAT_CHECK_RFC_DESTINATION
- 安装排错 max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
- Shell脚本:向磁盘中批量写入数据
热门文章
- 在 mac 系统上安装 python 的 MySQLdb 模块
- error: ‘xxx’ does not name a type
- COUNT(*) vs COUNT(col)
- Retrofit RestAdapter 配置说明
- dependencies 和 starter
- Powershell&TFS_Part 1
- VMware vSphere 虚拟化简介
- Delphi XE2 之 FireMonkey 入门(4) - 控件天生可做容器
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_08 转换流_4_OutputStreamWriter介绍&;代码实现
- 发邮件--yagmail模块