bzoj1257 [CQOI2007]余数之和sum
Description
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7
Input
输入仅一行,包含两个整数n, k。
Output
输出仅一行,即j(n, k)。
Sample Input
5 3
Sample Output
7
HINT
50%的数据满足:1<=n, k<=1000 100%的数据满足:1<=n ,k<=10^9
正解:数学+分块。
$k \bmod i=k-\left \lfloor \frac{k}{i} \right \rfloor*i$,然后直接数论分块即可。
注意$k<n$加特判。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <complex> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cstdio> 8 #include <vector> 9 #include <cmath> 10 #include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define inf (1<<30) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 ll n,k,lim,pos,ans; 23 24 il void work(){ 25 cin>>n>>k; lim=min(n,k); 26 if (n>k) ans+=k*(n-k); 27 for (RG ll i=1;i<=lim;i=pos+1){ 28 pos=k/(k/i); if (pos>lim) pos=lim; 29 ans+=(pos-i+1)*k-(k/i)*((i+pos)*(pos-i+1)>>1); 30 } 31 printf("%lld",ans); return; 32 } 33 34 int main(){ 35 File("sum"); 36 work(); 37 return 0; 38 }