区间 [m, n] 内的 17 的倍数构成公差 17 的等差数列,定位首末项后 O(1) 求和。
OJ: roj
题目 ID: 1066
难度:入门
标签:数论等差数列入门
创建: 2026-07-05 21:47
更新: 2026-10-04 23:57
题目描述
给定两个正整数
样例输入 50 85,样例输出 204(
思路
区间内的 17 的倍数构成公差为 17 的等差数列:首项取
参考代码
Python 版:
python
#!/usr/bin/env python3
# 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-07-05 21:47
# update_at: 2026-07-05 21:47
import sys
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
m = next(data)
n = next(data)
# 区间 [m, n] 中第一个能被 17 整除的数
first = m if m % 17 == 0 else m + (17 - m % 17)
# 等差数列求和:首项 first,末项 last,项数 k
last = n - n % 17
if first > last:
print(0)
return
k = (last - first) // 17 + 1
ans = (first + last) * k // 2
print(ans)
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-04 23:57
* update_at: 2026-10-04 23:57
*/
#include <iostream>
using namespace std;
typedef long long ll;
ll m, n;
ll first_term, last_term; // 区间 [m, n] 内 17 的第一个倍数、最后一个倍数
ll term_count; // 等差数列的项数
int main() {
cin >> m >> n;
// 首项:>= m 的最小 17 的倍数
if (m % 17 == 0) {
first_term = m;
} else {
first_term = m + (17 - m % 17);
}
// 末项:<= n 的最大 17 的倍数
last_term = n - n % 17;
if (first_term > last_term) { // 区间内没有 17 的倍数
cout << 0 << endl;
return 0;
}
// 符合条件的数构成公差为 17 的等差数列,首末项平均后乘项数
term_count = (last_term - first_term) / 17 + 1;
cout << (first_term + last_term) * term_count / 2 << endl;
return 0;
}