Hướng dẫn giải của Bedao Mini Contest 10 - STRAWBERRY
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả:
Đầu tiên ta gọi bội chung lớn nhất của ~A[i]~ sao cho không vượt quá ~x~ có dạng là ~A[i] * z~ , với ~z~ là số nguyên dương.
Ta có :
- Tổng tất cả các bội của ~A[i]~ đến bội lớn nhất không vượt quá ~x~ là ~(A[i] * 1) + (A[i] * 2) + (A[i] * 3) + ... + (A[i] * z) ~
- Đặt nhân tử chung là ~A[i]~ ta có biểu thức ~A[i] * ( 1 + 2 + 3 + ... + z)~
Vậy để tính được tổng các bội bé hơn ~A[i]~ ta chỉ cần tìm ~z~ và lấy ~A[i]~ nhân với tổng các số tự nhiên từ ~1~ đến ~z~. Việc tìm ~z~ chỉ đơn giản bằng cách dùng thao tác div ( chia lấy phần nguyên ) lấy ~x~ ~div~ ~A[i] ~ và trừ cho ~1~ nếu ~x~ chia hết cho ~A[i] ~ (đảm bảo ~A[i] *z ~ luôn bé hơn ~ x~).
Code mẫu
#include <bits/stdc++.h> #define ll long long using namespace std; void solve() { int n; cin >> n; ll x, ans = 0; cin >> x; for (int i = 1; i <= n; i++) { ll ai; cin >> ai; if (ai >= x) { ans += 0; continue; } ll sc = (long long)((x-1)/ai)*ai; ans += (sc + ai)*sc/(ai*2); } cout << ans; } int main() { //freopen("h.inp", "r", stdin); ios_base::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); solve(); return 0; }
Bình luận