[JLOI2015] 有意义的字符串 题解

news/2024/10/13 22:13:26

看到这个 \(7\times 10^{18}\) 的模数已经可以摆烂了。

不是,你告诉我这东西跟矩阵快速幂优化 DP 有关系??

观察到这个题显然不能硬做,因为你显然不能直接算小数部分,而且还有个取模很难受。

所以我们希望把一切的计算都基于整数。

这个时候我们就要思考,有什么东西可以把根号转化为整数。

直接平方再开方显然是不行的,因为你没办法开方取模。

于是,很神奇的东西出现了,你发现这个东西很像求根公式。

即方程 \(x^2-b\times x+\frac{b^2-d}{4}=0\) 的两个根分别为 \(\frac{b+\sqrt d}{2}\), \(\frac{b-\sqrt d}{2}\)

这个东西显然可以拿来降幂,即 \(x^n=b\times x^{n-1}+\frac{d-b^2}{4}\times x^{n-2}\)

所以你就可以直接通过矩阵快速幂求得 \(x^n=a\times x^0+b\times x^1\)\(a,b\)。但是有个问题是 \(x^1\) 并不是整数,而前面还有个取了模的系数 \(b\) 完全没办法向下取整。

发现一个有趣的事实是,对于这个方程的两个根,他们的和为 \(b\)

故我们考虑对于 \(f_n=(\frac{b+\sqrt d}{2})^n+(\frac{b-\sqrt d}{2})^n\) 进行降幂,即 \(f_i=b\times f_{i-1}+\frac{d-b^2}{4}\times f_{i-2}\),然后有 \(f_0=2,f_1=b\)。可以轻松求得 \(f_n\)

另外一个有趣的事实是这个奇怪的数据范围 \(b^2\le d \le (b+1)^2\)。可以发现,当 \(n\) 为偶数,有 \(0\le (\frac{b-\sqrt d}{2})^n \le 1\),否则为奇数时,有 \(-1\le (\frac{b-\sqrt d}{2})^n \le 0\)。用人话说就是当 \(n\) 为偶数并且 \(b^2\not=d\) 时,答案就是 \(f_n-1\),否则就是 \(f_n\)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 7528443412579576937ll;
ll add(ll x, ll y){return (1ull * x + 1ull * y) % mod;}
ll mul(ll x, ll y)
{ll sum = 0;while(y){if(y & 1) sum = add(sum, x);y >>= 1, x = add(x, x);}return sum;
}
struct matrix
{vector<vector<ll> > a;matrix operator *(const matrix &c)const{matrix now;int n = a.size(), m = c.a.size(), l = c.a[0].size();now.a.resize(n);for (int i = 0; i < n; ++i) now.a[i].resize(l); for (int i = 0; i < n; ++i){for (int j = 0; j < l; ++j){for (int k = 0; k < m; ++k)now.a[i][j] = add(now.a[i][j], mul(a[i][k], c.a[k][j]));}}return now;}matrix(){}matrix(int len1, int len2, int op = 1){a.resize(len1);for (int i = 0; i < len1; ++i) a[i].resize(len2);if(op) for (int i = 0; i < len1; ++i) a[i][i] = 1;}
};
ll b, d, n;
matrix ksm(matrix x, ll y)
{matrix sum(2, 2);while(y){if(y & 1) sum = sum * x;x = x * x, y >>= 1;}return sum;
}
int main()
{cin >> b >> d >> n;if(!n){puts("1");return 0; }matrix now(2, 2), a(1, 2);now.a[0][0] = b, now.a[1][0] = (d - b * b) / 4, now.a[0][1] = 1, now.a[1][1] = 0;a.a[0][0] = b, a.a[0][1] = 2;now = ksm(now, n - 1);a = a * now;if(b * b != d && n % 2 == 0) a.a[0][0]--;cout << a.a[0][0] << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/71234.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

标题、导航、目录添加序号

在主题文件夹添加base.user.css文件,把下面的内容复制进去。/*************************************** Header Counters in Content**************************************//** initialize css counter */ #write {counter-reset: h1 }h1 {counter-reset: h2 }h2 {counter-r…

qt深入解析

1.Qt IO 设备类型:顺序存储设备:如网卡。。 随机存储设备:如.txt..Qt中IO设备继承图 Qt中的文件系统 通用开发库,跨平台 QIODevice IO父类,提供字节块读写通用操作和基本接口 QFileDevice提供文件操作通用实现 QFile访问本地文件或嵌入资源 QTemporayFile创建和访问本地系…

安装WSL2

1.简介 SWL2是windows平台上的linux系统,有一定的优点和限制,最差的一点就是网络了,只能使用NAT相似的技术,不能完全替代虚拟机. 官网资料很详细了,也不是太多,这里只是提供快速入门. 2.初始安装 2.1.打开虚拟平台和WSL2.2.installl wsl2 #1.设置wsl版本 PS C:\Users\pc> ws…

这是我见过最通俗易懂的SVD(奇异值分解)算法介绍

线性代数是机器学习领域的基础,其中一个最重要的概念是奇异值分解(SVD),本文尽可能简洁的介绍SVD(奇异值分解)算法的基础理解,以及它在现实世界中的应用。 SVD是最广泛使用的无监督学习算法之一,它在许多推荐系统和降维系统中居于核心位置,这些系统是全球公司如谷歌、…

.NET云原生应用实践(二):Sticker微服务RESTful API的实现

本章目标完成数据访问层的基本设计 实现Sticker微服务的RESTful API引言:应该使用ORM框架吗? 毋庸置疑,Sticker微服务需要访问数据库来管理“贴纸”(也就是“Sticker”),因此,以什么方式来存储数据,就是一个无法绕开的话题。如果你遵循领域驱动设计的思想,那么你可以说…