前言

首先感谢所有帮助我卡常的大佬们。

题意

求 \((\sum_{i = 0}^{n} a^i b^{n - i})\mod p\) 的值(\(n \leq 10^{18}\),\(p\) 不一定为质数)。

分析

看到数据范围,首先想到快速幂 \(+\) 乘法逆元或者矩阵乘法。

但是看到 \(p\) 不为质数,那就只有可能是矩阵乘法了。

设 \(S_n = \sum_{i = 0}^{n} a^i b^{n - i}\),

则有 \(S_{n + 1} = \sum_{i = 0}^{n} a^ib^{n + 1 - i} + a^{n + 1}b^0 = b \sum_{i = 0}^{n} a^ib^{n - i} + a^{n + 1} = S_{n} \times b + a^{n + 1}\)。

有了递推式,我们就可以设出矩阵。

设向量 \(\begin{bmatrix}
S_n & a^n
\end{bmatrix}\),则有如下等式:

\[\begin{bmatrix} S_n & a^n \end{bmatrix}
\times
\begin{bmatrix} b & 0 \\ a & a \end{bmatrix}
= \begin{bmatrix} S_{n + 1} & a^{n + 1} \end{bmatrix}\]

矩阵乘法不会的点这里矩阵乘法

剩下的就交给矩阵快速幂了。

几个注意事项:

  1. 两个 long long 相乘会爆,要用 __int128
  2. 矩阵乘法要展开循环。否则会超时。
  3. 一定要快读快写!!

代码示例

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio> using namespace std; #define LL long long
#define PII pair<int, int>
#define PLL pair<LL, LL>
#define Int __int128 LL T;
Int ans[2], t[2][2]; namespace FastIO {
char buf[1 << 21], *_now = buf, *_end = buf;
#define getchar() (_now == _end && (_end = (_now = buf) + fread(buf, 1, 1 << 20, stdin), _now == _end) ? EOF : *_now ++ )
void read() { return; }
template <typename T, typename ...T2>
void read(T &s, T2 &...oth) {
s = 0; int f = 1; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = ~f + 1;
for (; ch >= '0' && ch <= '9'; ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48);
s *= f; read(oth...); return;
}
void write() { return; }
template <typename T, typename ...T2>
void write(T s, T2 ...oth) {
if (s == 0) { putchar('0'), putchar('\n'); write(oth...); return; }
int stk[100], top = 0;
if (s < 0) putchar('-'), s = ~s + 1;
while (s) stk[ ++ top] = s % 10, s /= 10;
do putchar(stk[top -- ] + (1 << 4) + (1 << 5)); while (top);
putchar('\n'); write(oth...); return;
}
}
#define read FastIO::read
#define write FastIO::write
#define Inline __inline__ __attribute__((always_inline)) Inline void mul(Int ans[], Int a[], Int b[][2], LL p)
{
Int tmp[2] = {0};
tmp[0] = (tmp[0] + (Int)a[0] * b[0][0]) % p;
tmp[0] = (tmp[0] + (Int)a[1] * b[1][0]) % p;
tmp[1] = (tmp[1] + (Int)a[0] * b[0][1]) % p;
tmp[1] = (tmp[1] + (Int)a[1] * b[1][1]) % p;
memcpy(ans, tmp, sizeof tmp);
} Inline void mul(Int ans[][2], Int a[][2], Int b[][2], LL p) {
Int tmp[2][2] = {0};
tmp[0][0] = (tmp[0][0] + (Int)a[0][0] * b[0][0]) % p;
tmp[0][0] = (tmp[0][0] + (Int)a[0][1] * b[1][0]) % p;
tmp[0][1] = (tmp[0][1] + (Int)a[0][0] * b[0][1]) % p;
tmp[0][1] = (tmp[0][1] + (Int)a[0][1] * b[1][1]) % p;
tmp[1][0] = (tmp[1][0] + (Int)a[1][0] * b[0][0]) % p;
tmp[1][0] = (tmp[1][0] + (Int)a[1][1] * b[1][0]) % p;
tmp[1][1] = (tmp[1][1] + (Int)a[1][0] * b[0][1]) % p;
tmp[1][1] = (tmp[1][1] + (Int)a[1][1] * b[1][1]) % p;
memcpy(ans, tmp, sizeof tmp);
} Inline void solve(LL a, LL b, LL n, LL p) {
ans[0] = 1, ans[1] = 1;
t[0][0] = b, t[0][1] = 0, t[1][0] = a, t[1][1] = a;
while (n) {
if (n & 1) mul(ans, ans, t, p);
mul(t, t, t, p); n >>= 1;
}
write(ans[0]);
} int main() {
read(T);
while (T--) {
LL n, a, b, p;
read(n, a, b, p);
solve(a, b, n, p);
} return 0;
}

P5137 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. C++指针和地址偏移在HotSpot VM中的应用

    在前面我们介绍过new运算符,这个操作实际上上包含了如下3个步骤: 调用operator new的标准库函数.此函数会分配一块内存空间以便函存储相应类型的实例. 调用相应类的构造函数 返回一个指向该对 ...

  2. Q-REG论文阅读

    Q-REG Jin, S., Barath, D., Pollefeys, M., & Armeni, I. (2023). Q-REG: End-to-End Trainable Point ...

  3. 虹科技术|Redis企业版数据库:实现金融服务IT现代化!

    随着新冠肺炎和技术创新推动企业进入新的数字时代,金融行业客户现在需要一种快速.简单且根据需求量身定制的数字银行体验.这就需要银行进行转型,以提供更加数字化的服务,但无论战略.方法,还是满足消费者极高期 ...

  4. 极速指南:在 SpringBoot 中快速集成腾讯云短信功能

    前言 今天分享一个SpringBoot集成腾讯云短信的功能,平常除了工作,很多xdm做自己的小项目都可能用到短信,但自己去看文档挺费劲的,我这边就帮你节省时间,直接把步骤给你列出来,照做就行. 实战 ...

  5. `.NET Web`新人入门必学项目`EarthChat`

    .NET Web新人入门必学项目EarthChat EarthChat是一个基于.NET 7的实战项目,EarthChat提供了很多的最佳实践,EarthChat的目标也是成为一个很多人都喜欢的大型聊 ...

  6. 使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录

    前言 RabbitMQ 是一个功能强大的开源消息队列系统,它实现了高效的消息通信和异步处理. 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验. 特点 成熟,稳定 消息持久 ...

  7. 飞码LowCode前端技术:如何便捷配置出页面

    简介 飞码是京东科技平台研发部研发的低代码产品,可使营销运营域下web页面快速搭建.本文将从三个方面来讲解如何便捷配置出页面,第一部分从数据.事件.业务支持三个方面进行分析,第二部分从模板与页面收藏与 ...

  8. Langchain-Chatchat项目:5.1-ChatGLM3-6B工具调用

      在语义.数学.推理.代码.知识等不同角度的数据集上测评显示,ChatGLM3-6B-Base 具有在10B以下的基础模型中最强的性能.ChatGLM3-6B采用了全新设计的Prompt格式,除正常 ...

  9. STM32CUBEIDE中 Debug 和 Release 的作用/区别/使用场景

    基本主流IDE都有该功能选项例如Keil MDK, IAR, Eclipse, VS等, 这里使用STM32CUBEIDE来举例 创建STM32CUBEIDE工程后默认有2个目标选项 Debug / ...

  10. 聊聊Flink必知必会(五)

    聊聊Flink的必知必会(三) 聊聊Flink必知必会(四) 从源码中,根据关键的代码,梳理一下Flink中的时间与窗口实现逻辑. WindowedStream 对数据流执行keyBy()操作后,再调 ...