ta có thể thấy giữ 2 khi bình lên sẽ có khoảng cách nhất định thì các số trong khoảng đó sẽ có gtri nguyên là min của 2 số đó
vậy ta chỉ cần tìm khoảng gia trị thì sẽ tìm được giá trị cần tìm
vậy ta sẽ từ b tìm khoảng giảm dần về sau và tìm số chinh phương gần nhất với b ở mỗi lần
vậy ở ta thấy ở mỗi lần b giảm xuống /sqrt(b) mỗi lần
nên dpt tổng quat chỉnh là O(/sqrt(b))
cpp#∈clude<bitsstdc++.h>usingnamespacestd;typedeflonglongll;const∫maxn=1e6;#def∈ei,j,x,nfor(∫i=j;i≤n;i+=x)#def∈en(i,j,x,n)for(∫i=j;i≥n;i≡x)∫ma∈(){iosbase::syncwithstdio(0);c∈.tie(0);cout.tie(0);lla,b,n;c∈〉a〉b;lls=0;whi≤(b≥a){llq=√b;n=q;q⋅=q;if(q<a)q=a;s+=n⋅(b-q+1);b=q-1;}cout〈s;return0;}cpp#∈clude<bitsstdc++.h>usingnamespacestd;typedeflonglongll;const∫maxn=1e6;#def∈ei,j,x,nfor(∫i=j;i≤n;i+=x)#def∈en(i,j,x,n)for(∫i=j;i≥n;i≡x)∫ma∈(){iosbase::syncwithstdio(0);c∈.tie(0);cout.tie(0);lla,b,n;c∈⟩a⟩b;lls=0;whi≤(b≥a){llq=√b;n=q;q⋅=q;if(q<a)q=a;s+=n⋅(b−q+1);b=q−1;}cout⟨s;return0;}
Đối với bài toán này ta có thể nhận thấy được một tính chất rằng:
Căn bậc hai của mọi số trong đoạn [l+1;r−1][l+1;r−1] đều bằng ⌊x⌋⌊x⌋, với l,rl,r là hai số chính
phương kế tiếp nhau.
Ví dụ: l=9l=9 và r=16r=16, lúc này căn bậc hai của mọi số trong đoạn [10;15][10;15] đều sẽ bằng x=3x=3.
Và đối với các cặp số chính phương kề nhau tiếp theo (l=16l=16, r=25r=25, ……), giá trị của xx
sẽ tăng lên 11.
Đến đây lời giải đã khá rõ ràng, vì số lượng số chính phương ≤1012≤1012 chỉ có khoảng 106106 số
nên ta có thể thực hiện sinh toàn bộ số chính phương ≤1012≤1012 vào một mảng và sau đó dùng
**Binary search** tìm số chính phương đầu tiên ≥a≥a và số chính phương đầu tiên ≥b≥b, sau đó
ta chỉ việc tính tổng là xong.
**Code tham khảo (C++):**
cppconst∫N=1e6+5;constllMXN=1e12;→→r<ll>□;voit(){for(lli=1;i⋅i≤MXN;++i)□.pushback(i⋅i);}voolve(){lla,b;c∈〉a〉b;ll∑=0;∫first=lowerbound(□.beg∈(),□.end(),a)-□.beg∈();∫l∗=lowerbound(□.beg∈(),□.end(),b)-□.beg∈();∑+=(□[first]-a)⋅first;∑+=(b-□[l∗-1]+1)⋅l∗;for(∫i=first;i<l∗-1;++i){∑+=(□[i+1]-□[i])⋅(i+1);}cout〈∑〈′n′;}∫ma∈(){iosbase::syncwithstdio(false);c∈.tie(0);∈it();solve();}cppconst∫N=1e6+5;constllMXN=1e12;→−−→r<ll>□;voit(){for(lli=1;i⋅i≤MXN;++i)□.pushback(i⋅i);}voolve(){lla,b;c∈⟩a⟩b;ll∑=0;∫first=lowerbound(□.beg∈(),□.end(),a)−□.beg∈();∫l∗=lowerbound(□.beg∈(),□.end(),b)−□.beg∈();∑+=(□[first]−a)⋅first;∑+=(b−□[l∗−1]+1)⋅l∗;for(∫i=first;i<l∗−1;++i){∑+=(□[i+1]−□[i])⋅(i+1);}cout⟨∑⟨'n';}∫ma∈(){iosbase::syncwithstdio(false);c∈.tie(0);∈it();solve();}
**Độ phức tạp:** O(106)O(106)