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=1∑nkmodi
其中
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=1∑n(k−[ik]∗i)=n∗k−i=1∑n[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%(k∗i)可以表示成
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=l∑rx%(k∗i)=i=l∑r(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)∗(r−l+1)+k∗i=l∑r[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=l∑r[kx]%i=i=l∑rn%i=(r−l+1)∗n−i=1∑n[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;
}