3-牛客挑战赛 87题解

482 字
2 分钟
3-牛客挑战赛 87题解

链接:https://ac.nowcoder.com/acm/contest/130844/C 来源:牛客网

题目描述#

Papy 是出题组唯一的高中生,CirnoNine 为了欺负 Papy,给了他一道高中数学经典的等差乘等比的数列求和式:

f(n,a,b,q)=i=1n((a×i+b)×qi)\displaystyle f(n,a,b,q) = \sum\limits_{i=1}^{n} \Big( (a\times i+b)\times q^i \Big)

由于这个答案可能很大,CirnoNine 只要求 Papy 回答 f(n,a,b,q)modmf(n,a,b,q) \bmod m 即可。

输入描述:#

每个测试文件均包含多组测试数据。第一行输入一个整数 T (1T2×104)T\ (1 \leq T \leq 2 \times 10^4) 代表数据组数,每组测试数据描述如下:

第一行输入四个整数 m,a,b,q (2m109, 0a,b,q<m)m, a, b, q\ (2 \leq m \leq 10^9,\ 0 \leq a, b, q < m),含义如题。

第二行输入一个二进制整数 n (1n<25000000)n\ (1 \leq n < 2^{5\,000\,000}),保证 nn 不存在前导 00,含义如题。

除此之外,保证单个测试文件的二进制整数的长度之和(即 1+log2n\lfloor 1 + \log_2 n \rfloor 之和)不超过 5×1065 \times 10^6

输出描述:#

对于每一组测试数据,新起一行输出一个整数表示 f(n,a,b,q)modmf(n,a,b,q) \bmod m

矩阵快速幂

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void solve() {
ll MOD, a, b, q;
string n;
cin >> MOD >> a >> b >> q;
cin >> n;
ll p = 1 % MOD; // q^0
ll g = 0; // sum q^i
ll h = 0; // sum i*q^i
ll x = 0; // 当前前缀对应的值 mod MOD
for (char c : n) {
ll p2 = p * p % MOD;
ll g2 = g * ((1 + p) % MOD) % MOD;
ll h2 = (h * ((1 + p) % MOD) % MOD + p * x % MOD * g % MOD) % MOD;
ll x2 = x * 2 % MOD;
if (c == '1') {
p2 = p2 * q % MOD;
g2 = (g2 + p2) % MOD;
h2 = (h2 + (x2 + 1) % MOD * p2) % MOD;
x2 = (x2 + 1) % MOD;
}
p = p2;
g = g2;
h = h2;
x = x2;
}
cout << (a % MOD * h % MOD + b % MOD * g % MOD) % MOD << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) solve();
}

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

3-牛客挑战赛 87题解
https://skaco2.com/posts/03-solutions/3-牛客挑战赛-87题解/
作者
SKACO2
发布于
2026-04-16
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
SKACO2
Hello……
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
53
分类
8
标签
54
总字数
58,255
运行时长
0
最后活动
0 天前

目录