数学-数论分块

在这里插入图片描述

ans = 0;
for(int l = 1, r; l <= n; l = r + 1)
{
    r = n / (n / l);
    ans += n / l * (r - l + 1);
}

在这里插入图片描述

在这里插入图片描述

 分块后我们发现每一块 然后去计算就行
 公差为k/left
#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n, k, ans = 0;
    long long left = 1, right, rest;
    scanf("%lld%lld", &n, &k);
    while (left <= n && left <= k) //求从1到min(n, k)内的总和
    {
        right = min(k / (k / left), n);	
        rest = k % left;
        ans += (rest + rest - (right - left) * (k / left)) * (right - left + 1) / 2;
        left = right + 1;
    }
    if (n > k)
    {
        ans += k * (n - k);
    }
    cout << ans;
}














[数论分块运用](https://codeforces.com/gym/103055/problem/F)
#include <bits/stdc++.h>
using  namespace std;
typedef long long ll;
 int  n,m;

int f(int  t)
{
    return n-m+(m-1)/t*t;
}

int B(int st,int ed,int num)
{
    int ans=1e8;
    int r=0;
    ed=min(ed,num);
    for(int i=st;i<=ed;i=r+1)
    {
        r= min(ed,num/(num/i));
        if(f(i)>=0)
        {
            ans=min(ans,f(i));
        }
    }
    return ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {

        cin>>n>>m;
        if(n>=m)cout<<abs(n-m)<<endl;
        else if(m%n==0)cout<<0<<endl;
        else cout<<B(1,n,m-1)<<endl;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值