1 条题解
-
0
📝 题目大意
给定六个非负整数 (每个 ),满足 。求 对 取模的结果。
💡 解题思路
-
题目分析:每个输入数最大可达 ,三个数相乘可达 ,远超 64 位整数范围。因此不能直接计算乘积再取模,必须借助模运算性质,边乘边取模。同时,由于题目保证 ,真实差值非负,但模意义下 可能小于 ,需要额外处理。
-
算法推导:
- 利用模运算性质:$(A \times B \times C) \bmod MOD = ((A \bmod MOD) \times (B \bmod MOD) \times (C \bmod MOD)) \bmod MOD$。
- 但直接计算 仍可能溢出
long long(),因此使用__int128作为中间类型来承接两个long long的乘积。 - 代码中
abc = (__int128)a * b % MOD * c % MOD的执行顺序为:- 先将
a转为__int128,与b相乘(128 位不会溢出); - 对
MOD取模,结果回到long long范围; - 再与
c相乘(此时两数都在MOD量级,乘积不会溢出__int128); - 再对
MOD取模,得到 。
- 先将
- 同理计算
def = (__int128)d * e % MOD * f % MOD。 - 最终结果:,加
MOD防止模运算下出现负数。
-
边界与细节:
- 输入可能为 ,处理方式与正常数一致, 的模运算结果仍为 。
- 必须使用
__int128(GCC/Clang 扩展),标准 C++ 的long long不足以安全承接两次 级别的乘法。若环境不支持__int128,可改用unsigned long long配合((a % MOD) * (b % MOD)) % MOD的方法(因为MOD < 2^31,两个小于MOD的数相乘不会溢出long long)。 - 虽然题目保证真实差值非负,但取模后
abc与def的大小关系不确定,必须通过+ MOD再取模来保证结果在 范围内。
⏱️ 复杂度分析
- 时间复杂度: — 仅进行常数次乘法和取模运算。
- 空间复杂度: — 只使用常数个变量。
💻 标准代码 (C++)
#include <iostream> using namespace std; const long long MOD = 998244353; // 模数 int main() { long long a, b, c, d, e, f; cin >> a >> b >> c >> d >> e >> f; // 使用 __int128 作为中间类型,避免两个 10^18 级别数相乘溢出 long long // 先计算 a*b 并对 MOD 取模,再乘以 c 再取模,得到 (A*B*C) mod MOD __int128 abc = (__int128)a * b % MOD * c % MOD; // 同理计算 (D*E*F) mod MOD __int128 def = (__int128)d * e % MOD * f % MOD; // 输出 (abc - def) mod MOD,+MOD 保证结果非负 cout << (long long)((abc - def + MOD) % MOD) << endl; return 0; } -
- 1
信息
- ID
- 649
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者