余数求和【除法分块】

P2261 [CQOI2007]余数求和【除法分块】

题意:
给出正整数 n n n k k k,请计算
G ( n , k ) = ∑ i = 1 n k   m o d   i G(n,k)=\sum _{i=1}^n k\bmod i G(n,k)=i=1nkmodi
其中 k   m o d   i k\bmod i kmodi 表示 k k k 除以 i i i 的余数。
例:G(10,5)=0+1+2+1+0+5+5+5+5+5=29。

因为 k   m o d   i k\bmod i kmodi可以表示成 k − [ k i ] ∗ i k-[\frac{k}{i}]*i k[ik]i,所以
G ( n , k ) = ∑ i = 1 n ( k − [ k i ] ∗ i ) = n ∗ k − ∑ i = 1 n [ k i ] ∗ i G(n,k)=\sum _{i=1}^n (k-[\frac{k}{i}]* i)=n*k-\sum _{i=1}^n [\frac{k}{i}]* i G(n,k)=i=1n(k[ik]i)=nki=1n[ik]i
n = k = 25 n=k=25 n=k=25时, [ k i ] [\frac{k}{i}] [ik]的值:
在这里插入图片描述

#include<algorithm>
#include<iostream>
//#include<stdio.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    LL n,k,ans;
    cin>>n>>k;
    ans=n*k;
    for(LL l=1,r;l<=n;l=r+1)//l总是倍数相同时,最小的那一个数
    {
        if(k/l==0)break;//k<i时,k%i=k
        r=min(k/(k/l),n);//通过l求r
        ans-=(k/l)*(l+r)*(r-l+1)/2;
    }
    /*
    for(int l=1,r;l<=n;l=r+1)
	{
		r=n/(n/l);
		ans+=(r-l+1)*(n/l);
	}*/
    cout<<ans<<endl;
    return 0;
}
power oj 2886: 大力出奇迹

在这里插入图片描述
题解:
因为 x % ( k ∗ i ) x\%(k*i) x%(ki)可以表示成 x % k + ( [ x k ] % i ) ∗ k x\%k+([\frac{x}{k}]\%i)*k x%k+([kx]%i)k,所以
a n s = ∑ i = l r x % ( k ∗ i ) = ∑ i = l r ( x % k + ( [ x k ] % i ) ∗ k ) ans=\sum\limits _{i=l}^r x\%(k*i)=\sum\limits _{i=l}^r (x\%k+([\frac{x}{k}]\%i)*k) ans=i=lrx%(ki)=i=lr(x%k+([kx]%i)k)
a n s = ( x % k ) ∗ ( r − l + 1 ) + k ∗ ∑ i = l r [ x k ] % i ans=(x\%k)*(r-l+1)+k*\sum\limits _{i=l}^r [\frac{x}{k}]\%i ans=(x%k)(rl+1)+ki=lr[kx]%i
n = [ x k ] n=[\frac{x}{k}] n=[kx]通过上一题可知:
∑ i = l r [ x k ] % i = ∑ i = l r n % i = ( r − l + 1 ) ∗ n − ∑ i = 1 n [ n i ] ∗ i \sum\limits _{i=l}^r [\frac{x}{k}]\%i=\sum\limits _{i=l}^r n\%i=(r-l+1)*n-\sum\limits _{i=1}^n [\frac{n}{i}]* i i=lr[kx]%i=i=lrn%i=(rl+1)ni=1n[in]i

#include<algorithm>
#include<iostream>
//#include<stdio.h>
#include<vector>
#include<string>
#include<cstring>
#include<math.h>
#include<iomanip>
using namespace std;
//#define int long long
typedef long long LL;
const int manx=4e5+10;
const int manx2=1e7+10;
const int mod=1e9+7;
const double inf=1e9+7;

int main()
{
    ios::sync_with_stdio(false);
    LL t,ll,rr,x,k;;
    cin>>t;
    while(t--)
    {
        cin>>ll>>rr>>x>>k;
        LL ans=(x%k)*(rr-ll+1)%mod;
        LL n=x/k;
        LL temp=n*(rr-ll+1);
        for(LL l=1,r;l<=rr;l=r+1)
        {
            if(n/l==0)break;
            r=min(n/(n/l),rr);
            LL l2=max(l,ll);
            if(l2<=r)
                (temp-=(n/l)*(((r-l2+1)*(r+l2)/2)%mod))%=mod;
        }
        temp=(temp+mod)%mod;
        (temp*=k)%=mod;
        cout<<(ans+temp)%mod<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值