专栏文章
题解:AT_abc428_d [ABC428D] 183184
AT_abc428_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minkdadj
- 此快照首次捕获于
- 2025/12/02 03:50 3 个月前
- 此快照最后确认于
- 2025/12/02 03:50 3 个月前
赛时因为精度问题被卡 分钟。
分析
考虑把题面里的 表示出来。
设 的位数为 ,则有:
因为我们要求得到的这个数是完全平方数,那么可以将其记为 ,其中 是正整数:
整理得:
因为 是有范围的:
1 \le x \le D \\
10^{q-1} \le C + x \le 10^q - 1
\end{array}\right.$$
这里记最终得到的 $x$ 的范围是 $[l,r]$,则有:
$$l + (C \times 10^q + C) \le m^2 \le r+ (C \times 10^q + C)$$
此时,将不等式左右两边同时开根号,注意取整问题,解出的 $m$ 的个数就是 $x$ 的个数。
最后,对于每个不同的可能的 $q$,分别计算后相加即可。这里的 $q$ 很小。
**注意 ```double``` 精度问题!**
时间复杂度 $\mathcal{O}(T)$。
---
:::success[[Submission #70267958](https://atcoder.jp/contests/abc428/submissions/70267958)]
```cpp
#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;
}
```
:::相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...