整除分块 B - Make Divisible

一个小知识点,昨天遇到了发现自己一直没学过。

整除分块。
Time:o(sqrt(n))

应用场景

:给定了一个数x,想要得到x除以从1到x所有数的结果的时候可以用到,举一个x为20的例子
请添加图片描述

结论:

可以发现的是,越是到了后方,越能发现很多连在一起的数被x除了之后得出的答案是一样的。

实现:

我们是否可以利用代码来枚举出来呢。

 for(int l=a,r=a;l<=b;l=r)
 {
            r=b/(b/l);
            r+=(r==l);
            int k=b/l;
 }

代码中的k就是我们要求的倍数,l和r代表的是:x除以一段区间内所有数都得出相同的值,那么这段区间的左右端点是多少,当然我们想要k不重复的话直接利用下面这段代码也可以

 for(int l=a,r=a;l<=b;l=r+1)
 {
            r=b/(b/l);
            int k=b/l;
 }

所以,,很简单,对吧。

例题:

B - Make Divisible

题意:给定一个a和一个b,求出最小的x+y,使得(b+y)%(a+x)==0

思路:从小到大枚举a,假设当前枚举值是A,kA是A的倍数中最接近b的那个数,然后求出a变成A的花费为X,b变成kA的花费为Y。

那么重点就是如何枚举这个A呢?我们发现反正是要用到k*A和b去比较,所以如果两个不同的A/b得到了同一个k的话实际上是无效的,所以要尽量避免无用的A枚举。

Time:O(sqrt(n)*T)

#include <bits/stdc++.h>
using namespace std;

signed main()
{
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t,a,b,k,w,ans;
    for(cin>>t;t;t--)
    {
        cin>>a>>b;
        if(a>=b)
        {
            cout<<a-b<<endl;
            continue;
        }
        ans=2e9+100;
        for(int l=a,r=a;l<=b;l=r)
        {
            r=b/(b/l);
            r+=(r==l);
            k=b/l;
            if(b%l) k++;
            w=l-a+k*l-b;
            w<ans?ans=w:0;
        }
        cout<<ans<<endl;
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值