专栏文章
题解:AT_abc428_d [ABC428D] 183184
AT_abc428_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minkeybq
- 此快照首次捕获于
- 2025/12/02 03:51 3 个月前
- 此快照最后确认于
- 2025/12/02 03:51 3 个月前
AT_abc428_d [ABC428D] 183184
小清新思维题。
Solution
看到这个题一般都会想到去枚举完全平方数,然而 最大可以达到 量级,不可行。
我们不妨换一个思路,注意到在钦定了 的位数 的前提下, 能表示的是一个连续的范围。设 分别为这个范围的上界和下界,则有:
需要和 取 是因为 的位数必须为 ,不能有前导零。
易证对于一段连续的区间 ,若 都在这段区间内,则对任意 , 都在这段区间内。令 分别为能使它的平方被区间包含的最小值/最大值,则有:
枚举 ,累加 。
注意可能需要额外注意数据溢出的问题。
Code
CPP#include<bits/stdc++.h>
#define int long long
#define ull unsigned int
using namespace std;
const int N = 200005;
ull t,c,d;
ull pw[N];
int p10(ull a)
{
int ret = 0;
while (a) ret++,a /= 10;
return ret;
}
signed main()
{
ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
pw[0] = 1;
for (int i = 1; i <= 18; i++)
pw[i] = pw[i-1]*10;
cin >> t;
while (t--)
{
cin >> c >> d;
int ans = 0;
for (int i = p10(c+1); i; i++)
{
ull l = c*pw[i]+max(pw[i-1],c+1),r = min((c+1)*pw[i]-1,c*pw[i]+c+d);
if (l > r) break;
ull beg = (int)sqrtl(l-1)+1,las = sqrtl(r);
if (beg > las) continue;
ans += las-beg+1;
if (p10(r) >= 19) break;
}
cout << ans << '\n';
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...