Ý tưởng
Ta giả sử dãy cần tính tổng của chúng ta như sau:
x + x + ... + x + ((x+1) + ... + (x+1)) + ((x+2) + ... + (x+2)) + ... + ((x+y-1) + ... + (x+y-1)) + ((x + y) + (x + y) + ... + (x+y))
Có b - a + 1 số hạng trong phép tính trên
Dễ thấy, ta luôn có x + 1 số x+1, x+2 số x+2, ..., x+y-1 số x+y-1
Gọi số số x là u, số số (x+y) là v. Vậy ta có thể viết lại biểu thức trên bằng cách:
x * u + (x+1) ^ 2 + (x+2)^2 + ... + (x+y-1)^2 + (x+y)*v
Ta sẽ tách biểu thức trên thành 3 phần:
- Phần đầu: x*u
- Phần thứ 2: (x+1) ^ 2 + (x+2)^2 + ... + (x+y-1)^2
- Phần thứ 3: (x+y)*v
Xử lý phần 1 và phần 3
Mình sẽ lấy phần 1 ra làm ví dụ
Để tính phần 1, ta cần phải tính x và tính u
Vậy tính x như thế nào? Ta để ý: Có tất cả 1 + 2 + 3 + ... + n số trước số có giá trị n + 1 đầu tiên của dãy. Gọi tổng 1 + 2 + 3 + ... + n là sum1(n). Sử dụng công thức, ta có sum1(n) = n*(n+1)/2.
Vậy ta cần tìm giá trị x sao cho sum1(x) >= a và sum1(x-1) < a.
=> Tìm kiếm nhị phân để tìm ra x
Khi ta đã có được giá trị của x, ta có thể dễ dàng tìm được u. Làm thế nào?
Do có sum1(n) các số trước số có giá trị n+1 đầu tiên và a - 1 số trước số có thứ tự a
=> u = sum1(x) - (a-1) = sum1(x) - a + 1
Vậy phần 1 đã được giải quyết
Phần 3 cũng tương tự, ta cũng tìm được (x+y), và rút ra được công thức v = b - sum1(y-1)
Xử lý phần 2
Ta thấy, phần 2 là tổng 1 dãy các số chính phương
Ta nhớ lại công thức tính sum2(n) = 1^2 + 2^2 + ... + n^2 = (n*(n+1)/2) + ((n-1)*n*(n+1)/3)
Mình sẽ để link cách chứng minh bên dưới
Vậy chẳng phải x^2 + (x+1)^2 + ... + y^2 = sum2(y) - sum2(x-1) sao?
Phần 2 đã được giải quyết
Cộng tất cả các kết quả của 3 phần lại, ta sẽ được đáp án cần tìm
Chú ý: Trường hợp đặc biệt
Nếu giá trị của x bằng giá trị của y, khi đó cách làm của chúng ta sẽ không còn đúng nữa
Vậy phải làm như thế nào?
Ta thấy nếu x = y thì tất cả các số trong khoảng a->b của dãy sẽ bằng x
Vậy ta sẽ in ra trực tiếp kết quả là x * (b-a+1)
Code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
// ll la long long (dong thu 2)
// Dung so lon de tranh bi tran so
ll a,b,lb,rb,lbs,rbs,ms;
ll sum1(ll n){
// Ham tim tong cac so tu 1 toi n
// Su dung cong thuc
return (n*(n+1))/2;
}
ll sum2(ll n){
// Tinh 1^2 + 2^2 + ... + n^2
// Su dung cong thuc
return (n*(n+1)/2) + ((n-1)*n*(n+1)/3);
}
ll getCurrent(ll x){
// Ham tim xem so thu x la so nao
// Su dung tim kiem nhi phan
ll left = 1,right = 1e9, mid, sumx = sum1(x);
while(left <= right){
mid = (left + right)/2;
if(sum1(mid-1) < x && x <= sum1(mid)) return mid;
if(sum1(mid) < x) left = mid+1;
else if(sum1(mid-1) >= x) right = mid-1;
}
}
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> a >> b;
lb = getCurrent(a); rb = getCurrent(b);
if(lb == rb){
// Truong hop dac biet neu so thu a bang so thu b
cout << lb * (b-a+1);
return 0;
}
// Tong ben trai
lbs = lb * (sum1(lb) - a + 1);
// Tong ben phai
rbs = rb * (b - sum1(rb-1));
// Tong o giua
ms = sum2(rb-1) - sum2(lb);
// cout << rb - lb > 1 << '\n';
cout << lbs + rbs + ms;
return 0;
}
uses crt;
var s, c : string;
i, a, b, K, j : integer;
function TX (z : byte) : string;
begin
TX := '';
c := chr(z + 48);
for j := 1 to z do TX := TX + c;
end;
begin
clrscr;
readln(a, b);
i := 1; S := '';
while length(S) < b do
begin
S := S + TX(i);
i := i + 1;
end;
K := 0;
for i := a to b do
begin
val(S[i], j);
K := K + j;
end;
write(K);
readln
end.
Tin học, tiếng Anh: informatics, tiếng Pháp: informatique, là một ngành khoa học chuyên nghiên cứu quá trình tự động hóa việc tổ chức, lưu trữ, xử lý và truyền dẫn thông tin của một hệ thống máy tính cụ thể hoặc trừu tượng (ảo). Với cách hiểu hiện nay, tin học bao hàm tất cả các nghiên cứu và kỹ thuật có liên quan đến việc mô phỏng, biến đổi và tái tạo thông tin.
Nguồn : Wikipedia - Bách khoa toàn thưLớp 8 - Năm thứ ba ở cấp trung học cơ sở, học tập bắt đầu nặng dần, sang năm lại là năm cuối cấp áp lực lớn dần nhưng các em vẫn phải chú ý sức khỏe nhé!
Nguồn : ADMIN :))Xem thêm tại https://loigiaisgk.com/cau-hoi or https://giaibtsgk.com/cau-hoi
Copyright © 2021 HOCTAPSGK