CF1870F Lazy Numbers 题解
题意:给一个长度为
直接做是不好办的,只能在一些数中找到
在手摸的过程中会发现一些长度相等的数之间会插入一些其它长度的数,很麻烦,考虑按长度分类。然后就可以发现
把这个东西看作一个类似于分段函数的东西,
观察这个函数,发现肯定是递增的,那么在这个函数中符合条件的点一定在
但这样并不好统计,显然的,因为
代码:
typedef long long ll;
ll n,m;
ll pw[65],c;
ll calc(ll a,ll b,ll c){
if(!b||!c)return 0;
return (b<=a/c)?(b*c):a;
}
ll check(int len,ll mid){
ll res=0,tmp=mid;
for(int i=len;i>=0;i--)res+=tmp-pw[i]+1,tmp/=m;
if(len==c)return res;
for(int i=len+1;i<c;i++)res+=pw[i-len]*(mid-pw[len]);
res+=calc(n+1,pw[c-len],mid)-pw[c];
return res;
}
void solve(){
cin>>n>>m;
pw[c=0]=1;while(pw[c]<=n/m)pw[c+1]=pw[c]*m,c++;
ll ans=0;
for(int i=0;i<=c;i++){
ll l=pw[i],r=((i==c)?n:(pw[i+1]-1)),L=r+1,R=l-1;
while(l<=r){
ll mid=(l+r)>>1;
if(check(i,mid)>=mid)r=mid-1;
else l=mid+1;
}
L=l;l=pw[i],r=((i==c)?n:(pw[i+1]-1));
while(l<=r){
ll mid=(l+r)>>1;
if(check(i,mid)<=mid)l=mid+1;
else r=mid-1;
}
R=r;
ans+=max(0ll,R-L+1);
}
cout<<ans<<"\n";
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;cin>>T;while(T--)solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!