前言

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

题意

求 \((\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. 【matplotlib基础】--3D图形

    matplotlib 在1.0版本之前其实是不支持3D图形绘制的. 后来的版本中,matplotlib加入了3D图形的支持,不仅仅是为了使数据的展示更加生动和有趣.更重要的是,由于多了一个维度,扩展了 ...

  2. Spring Boot RestController接口如何输出到终端

    背景 公司项目的批处理微服务,一般是在晚上固定时段通过定时任务执行,但为了预防执行失败,我们定义了对应的应急接口,必要时可以通过运维在终端中进行curl操作.然而,部分任务耗时较长,curl命令执行后 ...

  3. Redis中的缓存雪崩、缓存击穿、缓存穿透问题

    1. 什么是缓存雪崩 当我们提到缓存系统中的问题,缓存雪崩是一个经常被讨论的话题.缓存雪崩是指在某一时刻发生大量的缓存失效,导致瞬间大量的请求直接打到了数据库,可能会导致数据库瞬间压力过大甚至宕机.尤 ...

  4. 文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题

    三.用go语言,在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中,为什么不需要设置或重置对象的 prev 属性呢? 文心一言: 在 Go 语言中,ALLOCATE-OBJECT ...

  5. Java初始化顺序及使用Spring情况下初始化

    Java初始化顺序 1  无继承情况下的Java初始化顺序: class Sample {       Sample(String s)       {             System.out. ...

  6. vivo 网络端口安全建设技术实践

    作者:vivo 互联网安全团队 - Peng Qiankun 随着互联网业务的快速发展,网络攻击的频率和威胁性也在不断增加,端口是应用通信中的门户,它是数据进出应用的必经之路,因此端口安全也逐渐成为了 ...

  7. 如何正确执行 DORA 指标

    DevOps 研究与 DORA 评估指标可帮助我们深入了解软件开发和交付流程的性能和效率.这些指标包括部署频率.变更交付时间.变更失败率和平均恢复时间等方面.DORA 指标对于管理开发团队(从团队领导 ...

  8. Spring5学习随笔-Spring5的基本介绍、工厂设计模式

    学习视频:[孙哥说Spring5:从设计模式到基本应用到应用级底层分析,一次深入浅出的Spring全探索.学不会Spring?只因你未遇见孙哥] Spring系列-工厂 第一章.引言 Spring I ...

  9. Boruvka 算法

    Boruvka算法解决某些问题超级好用. 这些问题形如,给你n个点,每个点有点权,任意两个点之间有边权,边权为两个点权用过某种计算方式得出. 求最小生成树. 通常用 \(O(log n)\) 的时间可 ...

  10. Codeforces 1566E Buds Re-hanging

    原题链接 Codeforces Global Round 16 E. Buds Re-hanging 首先想到,如果我们把一个\(buds\)挂到一个叶子上,那么会使得叶子总数减\(1\). 还有就是 ...