专栏文章
题解:AT_abc397_d [ABC397D] Cubes
AT_abc397_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipuijvz
- 此快照首次捕获于
- 2025/12/03 18:10 3 个月前
- 此快照最后确认于
- 2025/12/03 18:10 3 个月前
1.前言
这一道题,乍一眼看,题面十分清晰:
给你一个 , 找出两个数 ,使得 。
你可能会想到直接枚举 ,通过公式 直接求出 ,但是你很快明白,这是不可能滴,因为数据范围 !
这样, 的范围是多少呢?
想象一个棱长为 的立方体,它的右前上方缺了一个立方体角,棱长为 ——它就是 ,此时,无论 有多大 ,这个 的左面有一个完整的长方体: ,则 ,由此可知, ,会TLE爆掉。
2.优化
要想解决这个问题,一定要老老实实遍历一个元素,既然 不行,那 也不抱希望了。怎么办呢?
联想之前的长方体,宽度 可以遍历,为了方便,令其为 ,可知 ,现在我们需要推导 的范围。
我们在之前构造的 中,它的左后下方有一个 的立方体,说明 。
时间复杂度超过 就会爆,现在循环遍历 ,循环内部留给我们的时间只有 ,所以,我们只能用二分算法枚举 ,时间复杂度 。
3.long long问题
利用 图推导出公式 为 ,这个公式的最大值约为 ,直接超
longlong。所以,我们定义 ,让二分够 ,则 初值可从 降为 。
4.AC code
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int n;
cin>>n;
int num=cbrt(n);
for(int i=1;i<=num;i++)
{
int m=n-i*i*i;
if(m%3) continue;
m/=3;
int l=1,r=sqrt(m/i)+i;
while(l<=r)
{
int mid=(l+r)/2;
int nu=i*mid*(mid-i);
if(nu==m)
{
if(mid==i) break;
cout<<mid<<' '<<mid-i;
return 0;
}
if(nu<m) l=mid+1;
else r=mid-1;
}
}
cout<<-1;
return 0;
}
——By AtCoder AC code
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...