星期以 7 天为周期,用快速幂求 a^b mod 7 后查星期表即可。
OJ: roj
题目 ID: 1083
难度:入门
标签:入门数学python
创建: 2026-09-29 17:55
更新: 2026-10-05 00:33
后置题目
roj 3608[NOIP2013-提高]转圈游戏B 直接复用 A 教的取模快速幂:A 用边乘边取模求 a^b mod 7,B 用同一算法求 10^k mod n 再算 (x+m·10^k) mod n,只是多加了环上位移可叠加的观察roj 3523[NOIP2003-普及] 麦森数B 的子问题二直接复用 A 教的模意义快速幂:都是把 a^b 的指数二进制拆解、每步乘法后取模以避免构造巨大整数,A 用它求 a^b mod 7 再查星期表,B 用 pow(2,P,10^500) 求 2^P mod 10^500 得到末 500 位,再叠加 A 未涉及的对数闭式位数与补零切行流程。roj 3000a^bA 教的「边乘边取模」快速幂(指数逐位右移、底数自平方、最低位为 1 时累乘)正是 B 的 mod_pow 原样用来求 a^b mod p 的一步,只是把固定模 7 换成任意模 p 并补上 p=1/b=0/a>=p 的边界。
题目描述
假设今天是星期日,那么过 3 2000,样例输出 Tuesday。
思路
星期以 week[r-1]:
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 17:55
# update_at: 2026-09-29 17:55
import sys
WEEK = [ # 星期名,下标 = (a^b mod 7) - 1:0 → Monday … 6 → Sunday
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
]
def solve() -> None:
a, b = map(int, sys.stdin.buffer.read().split())
r = pow(a, b, 7) # 三参数 pow 即模意义快速幂,大指数也不需要展开
print(WEEK[r - 1]) # r=0 表示整除 7,余 7 天一循环,仍是 Sunday
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 00:33
* update_at: 2026-10-05 00:33
*/
#include <cstdio>
typedef long long ll;
// 星期表按 Monday 开头存放:下标 r-1 对应"过 r 天"后的星期
// r = 0 时下标 -1,week[-1] 在 C++ 中不合法,所以单独特判成 Sunday
const char *week[6] = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
ll a, b; // 题目输入:底数 a,指数 b
int main() {
scanf("%lld %lld", &a, &b);
// 快速幂求 a^b mod 7:把 b 按二进制位拆开,边乘边取模,中间值不会膨胀
ll r = 1 % 7; // 注意 b 可能为 0 的写法习惯;本题 b>=1,1%7=1
ll base = a % 7;
while (b > 0) {
if (b & 1) r = r * base % 7;
base = base * base % 7;
b >>= 1;
}
if (r == 0)
printf("Sunday\n"); // a^b 是 7 的整数倍,正好过了整数个星期
else
printf("%s\n", week[r - 1]);
return 0;
}