题解:AT_abc428_d [ABC428D] 183184
InfiniteRobin · · 题解
赛时因为精度问题被卡
分析
考虑把题面里的
设
因为我们要求得到的这个数是完全平方数,那么可以将其记为
整理得:
因为
这里记最终得到的
此时,将不等式左右两边同时开根号,注意取整问题,解出的
最后,对于每个不同的可能的
注意 double 精度问题!
时间复杂度
:::success[Submission #70267958]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int calc(ll res){ //用于计算数字位数
int cnt = 0;
while(res){
cnt ++;
res /= 10;
}
return cnt;
}
ll qpow(ll x,int p){
ll ans = 1;
while(p){
if(p & 1) ans *= x;
p >>= 1;
x *= x;
}
return ans;
}
ll t,c,d;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>c>>d;
ll ans = 0;
int l = calc(c+1) ,r = calc(c + d);
for(int i=l;i<=r;i++){ //枚举 q
ll res = c * qpow(10,i) + c;
//计算 m^2 的范围
ll a = max(qpow(10,i-1)-c,1ll) + res, b = min(qpow(10,i) - 1 - c,d) + res;
long double aa = a , bb = b; //不用 long double 会 WA!
a = ceil(sqrt(aa)); b = floor(sqrt(bb));
ans += b - a + 1;
}
cout<<ans<<"\n";
}
return 0;
}
:::