洛谷P2261 整除分块模板

题意:

给出n,kn,kn,k,求出
∑i=1nk mod i \sum_{i=1}^{n}k\ mod\ i i=1nk mod i

Solution:

由于k mod i=k−⌊ki⌋⋅ik\ mod\ i=k-\lfloor\frac{k}{i}\rfloor\cdot ik mod i=kiki,于是只需要求
nk−∑i=1n⌊ki⌋⋅i nk-\sum_{i=1}^{n}\lfloor\frac{k}{i}\rfloor\cdot i nki=1niki
对于一段使⌊ki⌋\lfloor\frac{k}{i}\rfloorik相同的iii,可以利用等差数列求和这一段

现在考虑对于一个lll,如何找到最大的rrr满足
⌊kl⌋=⌊kr⌋ \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor lk=rk
有这样的等式满足
⌊kl⌋=⌊kr⌋≤kr \lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloor\leq\frac{k}{r} lk=rkrk
于是
r≤k⌊kr⌋=k⌊kl⌋⇒rmax=⌊k⌊kl⌋⌋ r\leq\frac{k}{\lfloor\frac{k}{r}\rfloor}=\frac{k}{\lfloor\frac{k}{l}\rfloor}\Rightarrow r_{max}=\lfloor\frac{k}{\lfloor\frac{k}{l}\rfloor}\rfloor rrkk=lkkrmax=lkk

此时找出了最大的[l,r][l,r][l,r]使⌊kl⌋=⌊kr⌋\lfloor\frac{k}{l}\rfloor=\lfloor\frac{k}{r}\rfloorlk=rk,只需要对r+1r+1r+1作为新的左端点时重新计算即可,并且当⌊kl⌋=0\lfloor\frac{k}{l}\rfloor=0lk=0时,r=+∞r=+\inftyr=+。无论何种情况,切莫忘记题目≤n\leq nn的限制

时间复杂度

i⋅j=ki\cdot j=kij=k

i≤ni\leq \sqrt{n}in时,j≥nj\geq \sqrt{n}jn,此时iii最多n\sqrt{n}n种取值,对应的jjj只可能有一个取值,于是此时最多有n\sqrt{n}n⌊ki⌋\lfloor\frac{k}{i}\rfloorik

同理对i≥ni\geq \sqrt{n}in,此时相当于i,ji,ji,j轮换,取值种数仍然是n\sqrt{n}n

于是总取值不超过2n2\sqrt{n}2n种,时间复杂度O(n)O(\sqrt{n})O(n)

// #include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bitset>
#include<map>
using namespace std;

using ll=long long;
const int N=1e5+5,inf=0x3fffffff;
const long long INF=0x3fffffffffffffff,mod=1e9+7;

ll n,k;

int main()
{
    cin>>n>>k;
    ll l=1,ans=1ll*n*k;
    while(l<=n)
    {
        ll val=k/l,r=val?min(n,k/val):n;
        ans-=1ll*(l+r)*(r-l+1)/2*val;
        l=r+1;
    }
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值